Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java streams non-interference and side-effects

Looking at Java java.util.stream package documentation a doubt arose regarding best practices to follow in streams usage. Considering this code:

HashMap<Integer,Integer> map = new HashMap<>();
map.put(1,1);
map.put(2,2);
map.put(3,3);
map.put(4,4);
map.keySet().parallelStream().forEach(key -> {
        if (key == 3) { 
            map.put(3,0);
        }
});
  1. Is code ouput always equals to ([1,1],[2,2],[3,0],[4,4])?
  2. Can map.put(3,0) be considered as a non interfering operation?
  3. Can map.put(3,0) be considered as an accetable side-effect?

In other words, the above code can be considered compliant with the best practices suggested in streams documentation?

like image 499
giuseppe maugeri Avatar asked Jan 27 '23 06:01

giuseppe maugeri


1 Answers

Your example definitely violates the non interference requirement:

For most data sources, preventing interference means ensuring that the data source is not modified at all during the execution of the stream pipeline. The notable exception to this are streams whose sources are concurrent collections, which are specifically designed to handle concurrent modification.

Your data source, a HashMap, is not designed to handle concurrent modification and therefore it should not be modified at all during the execution of the stream pipeline.

Therefore the answer to your 2nd and 3rd questions is no.

As for the first question, your specific code may still produce the expected result, since your condition ensures only one thread will ever call map.put(3,0). However, this is still considered an incorrect usage of Streams.

like image 189
Eran Avatar answered Jan 31 '23 09:01

Eran