Associativity means that regrouping operands does not change an operation’s result: x ⊕ (y ⊕ z) must equal (x ⊕ y) ⊕ z. Stream.reduce requires its accumulator to satisfy this rule, along with an identity value that leaves the other operand unchanged. section 9.5
The sequential-stream trap
A reduction that computes a List hash code with (x, y) -> x * 31 + y can produce the expected result sequentially even though the operation is not associative and 1 is not a valid identity. Replacing stream() with parallelStream() can produce a wrong result because grouping and computation order change. 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 standard List hash-code calculation with the reduction that appears correct sequentially but violates the Stream.reduce contract. section 9.5
Avoid the failure by:
- Checking both associativity and the identity requirement before passing an accumulator to reduce. section 9.5
- Treating code that works only on sequential streams as unsafe when parallel execution may occur. section 9.5




