Non, non, NON !
Dans les tâches à triplet unique, il n'est pas nécessaire d'utiliser l'Iterator, ni même CopyOnWriteArrayList (en raison des pertes de performances).
La solution est beaucoup plus simple : essayer d'utiliser la boucle for canonique au lieu de la boucle for-each .
Selon les détenteurs des droits d'auteur de Java (il y a quelques années Sun, maintenant Oracle) guide pour chaque boucle Il utilise un itérateur pour parcourir la collection et le cache simplement pour améliorer l'apparence du code. Mais, malheureusement, comme nous pouvons le voir, cela a produit plus de problèmes que de bénéfices, sinon ce sujet n'aurait pas été abordé.
Par exemple, ce code entraînera une exception java.util.ConcurrentModificationException lors de la prochaine itération sur une ArrayList modifiée :
// process collection
for (SomeClass currElement: testList) {
SomeClass founDuplicate = findDuplicates(currElement);
if (founDuplicate != null) {
uniqueTestList.add(founDuplicate);
testList.remove(testList.indexOf(currElement));
}
}
Mais le code suivant fonctionne très bien :
// process collection
for (int i = 0; i < testList.size(); i++) {
SomeClass currElement = testList.get(i);
SomeClass founDuplicate = findDuplicates(currElement);
if (founDuplicate != null) {
uniqueTestList.add(founDuplicate);
testList.remove(testList.indexOf(currElement));
i--; //to avoid skipping of shifted element
}
}
Essayez donc d'utiliser l'approche d'indexation pour itérer sur des collections et évitez la boucle for-each, car elles ne sont pas équivalentes ! La boucle for-each utilise certains itérateurs internes, qui vérifient les modifications de la collection et lèvent l'exception ConcurrentModificationException. Pour le confirmer, regardez de plus près la trace de pile imprimée lors de l'utilisation du premier exemple que j'ai posté :
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at TestFail.main(TestFail.java:43)
Pour le multithreading, utilisez les approches multitâches correspondantes (comme le mot-clé synchronisé).