An accumulator combines two values during Stream.reduce. Its operation must be associative and must return the other operand unchanged when given the identity value. section 9.5
Check these requirements before relying on an accumulator:
- Verify that x ⊕ (y ⊕ z) equals (x ⊕ y) ⊕ z for all operands. section 9.5
- Verify that combining any value with the identity leaves that value unchanged. section 9.5
- Do not treat sequential success as proof of correctness: invalid accumulators can fail when computation becomes parallel. section 9.5
A sequentially convincing mistake
A List hash calculation can use reduce(1, (x, y) -> x * 31 + y) and produce the expected result sequentially. The accumulator is nevertheless non-associative and does not have the required identity, so parallelStream() can produce a wrong answer. section 9.5
List<String> list = List.of("a", "b", "c", "d");
System.out.println(list.hashCode()); #1
System.out.println(list.stream()
.mapToInt(Objects::hashCode)
.reduce(1, (x, y) -> x * 31 + y)); #2
Compare the direct List hash result with the reduce-based calculation and inspect the accumulator’s hidden contract violation. section 9.5



