java.util.ConcurrentModificationException Streams

  • A+
Category:Languages

I was trying the following code Java 8 SE I ran it directly from eclipse, it has the below-mentioned exception also I ran it with command prompt it produces the same result.

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); 

I am not sure as to why exactly it gives the following exception

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) 

Java version I am running with

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) 

 


This is because of subList,let me explain with different scenarios

From java docs docs

For well-behaved stream sources, the source can be modified before the terminal operation commences and those modifications will be reflected in the covered elements.

Except for the escape-hatch operations iterator() and spliterator(), execution begins when the terminal operation is invoked, and ends when the terminal operation completes.

Case 1: Successful (because the source can be modified before the terminal operation commences)

List<String> test = new ArrayList<>();     test.add("A");     test.add("B");     test.add("c");     //test = test.subList(0, 2);     Stream s = test.stream();     test.add("d");     s.forEach(System.out::println); 

Output :

A B c d 

Case 2: Failed for sublist different reference

List<String> test = new ArrayList<>();     test.add("A");     test.add("B");     test.add("c");     List<String> test1 = test.subList(0, 2);     Stream s = test1.stream();     test1.add("d");     s.forEach(System.out::println); 

Output :

A BException 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) at com.demo.Example.Main2.main(Main2.java:30) 

case 3: Failed for sublist same reference, Both lists are different

List<String> test = new ArrayList<>();     test.add("A");     test.add("B");     test.add("c");     System.out.println(test.hashCode()); //94401     test = test.subList(0, 2);     System.out.println(test.hashCode()); //3042     Stream s = test.stream();     test.add("d");     s.forEach(System.out::println); 

Output :

94401 3042 A B 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) at com.demo.Example.Main2.main(Main2.java:32) 

Final Conclusion

The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

From docs subList docs

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: