2017-06-13 2 views
4

Warum ist es passiert?unklar java.util.ConcurrentModificationException

Ich habe diesen Code geschrieben und es wirft java.util.ConcurrentModificationException

List<Integer> list = Stream.iterate(0, t -> t + 1).limit(10).collect(Collectors.toList()); 
System.out.println(list); 
List<Integer> subList = list.subList(5, list.size()); 
list.removeAll(subList); 
System.out.println(subList); 
System.out.println(list); 

Aber nächste Code wirft nicht

List<Integer> list = Stream.iterate(0, t -> t + 1).limit(10).collect(Collectors.toList()); 
System.out.println(list); 
List<Integer> subList = list.subList(5, list.size()); 
System.out.println(subList); 
list.removeAll(subList); 
System.out.println(list); 
+2

@Blasanka beheben Wo kommt das erste Code-Schnipsel Iterierte während einige Modifikationen zu tun? Hast du gesehen, dass der einzige Unterschied der Austausch von zwei Zeilen ist, von denen eine nur die Unterliste ausdruckt? – Seelenvirtuose

+0

Ich kenne Änderungen während der Listeniteration. Aber auf meine Art habe ich zwei Endbearbeitungen im Single Thread –

Antwort

4

an der Javadoc für das Verfahren subList() Sehen, es gibt eindeutig an:

Die Semantik der von dieser Methode zurückgegebenen Liste wird undefiniert, wenn die Sicherungsliste (d. H. Diese Liste) strukturell anders als anders als über die zurückgegebene Liste ist.

In Ihrem ersten Beispiel, das ist genau das, was passiert ist: Sie strukturell die Unterstützung Liste Modifizieren removeAll() durch den Aufruf, so dass das Verhalten Ihrer Unterliste ist jetzt nicht näher bezeichnet.

Die Tatsache, dass der nachfolgende Aufruf, die Liste zu drucken, endet mit einem ConcurrentModificationException werfen ist nur ein Detail der Implementierung.

Wenn Sie dies vermeiden wollen, würden Sie eine neue Liste aus der Unterliste erstellen müssen Sie abrufen, das heißt

List<Integer> subList = new ArrayList<>(list.subList(5, list.size())); 
list.removeAll(subList); 

können Beide Listen nun unabhängig abgerufen und geändert werden.

0

Vielen Dank, Robby Cornelissen.

Weiter Code wird

List<Integer> subList = new ArrayList<>(list.subList(5, list.size())); 
Verwandte Themen