J'ai trébuché sur cet étrange bug. On dirait que sorties p> on pourrait s'attendre à un collections.sort () code> ne modifie pas la liste triée d'une manière qui permet une détection de modifications simultanées lors de l'itération sur la même liste. Exemple de code:
ConcurrentModificationException code>, mais il n'est pas en cours de soulevée et Le code fonctionne bien que cela ne soit pas. P> p>
3 Réponses :
Pourquoi lancerait-il Notez que ConcurrentModificationException Strong> ne se produirait que lorsqu'un nouvel élément est ajouté à votre collection ou enlevez de votre collection en itération. c'est-à-dire que lorsque votre collection est modifiée de manière structurelle. P> (les modifications structurelles sont celles qui changent la taille de cette liste,
ou sinon la perturber de manière aussi la mode que les itérations en cours
peut donner des résultats incorrects.) p>
BlockQuote> Trier ne modifierait pas de manière structurelle votre collection, tout ce qu'il fait est de modifier la commande.
Le code ci-dessous lancerait Si vous regardez la source de la méthode de tri < href = "http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/collections.java" rel = "nofollow"> collections a > classe, elle ne lance pas Cette implémentation décharge la liste spécifiée dans un tableau, trie le
Array et compter sur la liste réinitialisant chaque élément de la
position correspondante dans le tableau. Cela évite le journal n2 (n)
performance qui résulterait de la tentative de trier une liste liée dans
Place. P>
blockQuote> La politique des itérateurs pour les collections Java 2 est d'échouer
rapide, comme décrit à la section 11.1: chaque fois qu'ils accèdent au support
collection, ils vérifient la modification structurelle (qui, dans
général, signifie que les éléments ont été ajoutés ou supprimés de la
collection). S'ils détectent la modification structurelle, ils échouent
immédiatement, jetant une exception concurrente plutôt que
continuer à tenter de parcourir la collection modifiée avec
Résultats imprévisibles. P>
blockQuote> p>
extrait du livre Generics et collections Java : h2>
+1. de la position correspondante dans le tableau i>
Je sais. J'ai vérifié ce code aussi. Je trouve toujours qu'il devrait y avoir un tel drapeau est défini dans trier () code>.
point équitable. Donc, c'est le fameux "C'est une fonctionnalité, pas un bogue". Une façon de résoudre le ... :-) Je ne vois toujours pas vraiment comment l'ajout est considéré comme un changement structurel tout en mélangeant son contenu n'est pas.
@Daniel Vérifiez ici dans la source ArrayList pour quoi MOYENS DE MODIFIÉ STRANTILISÉE B> dans le CODE Sevoir. GrepCode. Com / Fichier / Repository.GrepCode.com / Java / Root / JDK / Ouvrir JDK / ...
Parler de fonctionnalités Je ne vois pas pourquoi il ne faut pas lancer Les modifications structurelles sont celles qui changent la taille de la liste,
ou sinon la perturber de manière aussi la mode que les itérations en cours
peut donner des résultats incorrects. p>
blockQuote>
Je pense qu'il existe un argument pour affirmer que code> réorganiser code> réorganiser les éléments provoque l'itérateur de donner des résultats incorrects, mais je n'ai pas vérifié quels sont les résultats obtenus pour que l'itérateur soit défini. P >
Parler de la mise en œuvre, il est facile de voir pourquoi il ne: VOIR LA SOURCE POUR ArrayList et collections A>: p>
donc ConcurrentModificationException code>. Mais selon la documentation, l'itérateur jette l'exception lorsqu'il remarque que la modification structurelle et la modification structurelle est défini comme: p>
arraylist.modcount code> Changements avec les modifications structurelles telles que les modifications structurelles LI>
LISTITR code> Méthodes Entrez une copie de sa valeur dans
init code> et vérifiez qu'il n'a pas changé dans ses méthodes li>
collections.sort code> Appels
listitr.set code> Quel appels
arratlist.set code>. Cette dernière méthode n'incrément pas
modcount code> li>
ul>
listitr.next () code> voit le même
modcount code> et aucune exception n'est lancée. p>
Pour Android, cela dépend des versions API. De l'API 26, Collections # Trier (liste
Liste # Trier (comparateur Super E>) Code>. Donc, si vous triez
ArrayList code>, vous pouvez obtenir ConcurrentModificationException forte> selon que vous avez modifié la liste dans un autre fil. Voici le code source de
java / util / arraylist.java code> qui jette l'exception:
Vous n'avez pas deux threads; Il n'y a pas de concurrence (qui est vraiment i> à quoi cette exception était censée garder). Même dans ... Notez que le comportement de l'échec-rapide d'un itérateur ne peut pas être garanti tel qu'il est, d'une manière générale, impossible de faire des garanties difficiles en présence de modifications simultanées non synchronisées. Les itérateurs d'échec-Fast lancent une exception exceptionnelle sur une base de meilleur effort. Par conséquent, il serait faux d'écrire un programme qui dépendait de cette exception pour son exactitude: le comportement échec-rapide des itérateurs doit être utilisé uniquement pour détecter les bogues. I>
Eh bien, vous obtenez cette exception si vous ajoutez un élément à la liste (dans le même fil). Cela n'a pas de sens pour moi pourquoi l'on ajoute des éléments à la liste une opération illégale, mais chanterait la liste n'est pas ...
Parce que ce n'est pas i> Modification structurellement i> la liste
code>, les nœuds qui composent la liste sont toujours là et ils n'ont même pas changé de commande. Votre itérateur n'est pas affecté par une valeur contenue dans les nœuds changeant. En bref, il n'est vraiment pas censé vous protéger de vous-même.