The package summary of java.util.stream
states the following:
An example of a stateful lambda is the parameter to
map()
in:Set<Integer> seen = Collections.synchronizedSet(new HashSet<>()); stream.parallel().map(e -> { if (seen.add(e)) return 0; else return e; })...
Here, if the mapping operation is performed in parallel, the results for the same input could vary from run to run, due to thread scheduling differences, whereas, with a stateless lambda expression the results would always be the same.
I don't understand why this wouldn't produce consistent results, given that the set is synchronized and can only process one element at a time. Can you complete the above example in a way that demonstrates how the result could vary due to parallelization?
List<Integer> numbers = // fill it in with [1, 3, 3, 5]
List<Integer> collected = numbers.stream().parallel().map(...).collect(Collectors.toList());
collected
could contain either [0, 0, 3, 0] or [0, 3, 0, 0], depending on which of the middle two elements was processed first.
I'm not sure if this counts as a stateful per-se (if it does not I'll just delete this), but relying on anything that has state inside map
and the like is bad.
int[] arr = new int[3];
Stream.of(1, 2, 3)
.map(i -> {
arr[i] = i + 5;
return i * 2;
})
.count();
System.out.println(Arrays.toString(arr));
In jdk-9 this will produce an array with zeroes only, since there are no operations that change the Stream size (flatmap
or filter
), thus map
is never executed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With