Yuli Reiri
Yuli Reiri

Reputation: 591

java8 java.util.ConcurrentModificationException during forEach cycle

I use java8 streams. Here is the data structure I have:

Map< String, List< String >> mmessage = getSomeMessage();

Then I iterate via the map and list:

 mmessage.entrySet().stream().forEach( entry -> {
            entry.getValue().stream().forEach( li -> {
                if ( lis.indexOf( li ) == - 1 )  {
                    lis.add( lineItem );
                }
            });
        });

But get concurrent modification exception:

java.util.ConcurrentModificationException
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at com.web3.buyer.roomba.RoombaTurn.lambda$received$3(RoombaTurn.java:296)
    at java.util.Iterator.forEachRemaining(Iterator.java:116)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at com.web3.buyer.roomba.RoombaTurn.received(RoombaTurn.java:295)
    at com.web3.buyer.SystemBus.lambda$publishToTheQueue$0(SystemBus.java:51)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

From my understanding iterating via the map \ list should not cause this kind of behavior.

Upvotes: 7

Views: 6010

Answers (1)

Peter Lawrey
Peter Lawrey

Reputation: 533492

I would write this using a full functional style and you shouldn't run into the problem of modifying a list while iterating it.

List<String> strs = mmessage.values().stream()
                            .flatMap(List::stream)
                            .distinct()
                            .collect(Collectors.toList());

Upvotes: 17

Related Questions