Je tentais le code suivant Java SE 8 je l' ai couru directement à partir de l' éclipse, il a l'exception mentionnée ci-dessous aussi je l'ai couru avec invite de commande , il produit le même résultat.
List<String> test = new ArrayList<>();
test.add("A");
test.add("B");
test.add("c");
test = test.subList(0, 2);
Stream<String> s = test.stream();
test.add("d");
s.forEach(System.out::println);
Je ne suis pas sûr de savoir pourquoi exactement il donne l'exception suivante
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1388)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
version Java Je suis en cours d'exécution avec
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
un minimum de code
List<String> test = new ArrayList<>(Arrays.asList("java-8", "subList", "bug")).subList(0, 2);
Stream<String> stream = test.stream();
test.add("java-9");
stream.forEach(System.out::println); // any terminal operation
Java-8 [Bug]
Le code ci - dessus exécuté avec Java-8 lance une CME. Selon le javadocArrayList
Les itérateurs renvoyés par cette méthodes de classe itérateur et ListIterator sont fail-rapide : si la liste est structurellement modifiée à tout moment après l'itérateur est créé, de quelque manière que par propre supprimer ou ajouter des méthodes de l'itérateur, l'itérateur jetteront un
ConcurrentModificationException
.Ainsi, face à la modification concurrente, l'itérateur échoue rapidement et proprement, plutôt que de risquer arbitraire, le comportement non-déterministe à un moment non déterminé à l'avenir.
sortie :
java-8 subList Exception in thread "main" java.util.ConcurrentModificationException
Question
En vertu des directives similaires, la modification d' une collection alors qu'il est itéré est considéré comme une erreur de programmation et par conséquent de lancer ConcurrentModificationException
est effectué sur une base « best effort ».
Mais la question est, dans le code ci-dessus ne nous finissons par modifier la collection alors qu'il était ou plutôt itérer avant?
ne devrait pas être paresseux STREAM?
Sur la recherche de plus d' un tel comportement attendu, a trouvé quelque chose de similaire et fixe rapporté comme un bug - ArrayList.subList () spliterator () n'est pas la liaison tardive. Et cela a été corrigé avec Java-9.
Un autre bug lié à cette question - . ArrayList.subList () iterator () forEachRemaining () hors par une erreur.
Java-11 [fixe]
Bien que fixe en Java-9 selon le rapport de bogue, le test réel que je remplissais était la version LTS et le code comme partagé ci-dessus fonctionne sans exception.
sortie :
java-8 subList java-9