From reduce's documentation:
The identity value must be an identity for the accumulator function. This means that for all t, accumulator.apply(identity, t) is equal to t.
Which is not true in your case - "" and "a" creates "/a".
I have extracted the accumulator function and added a printout to show what happens:
BinaryOperator<String> accumulator = (s1, s2) -> {
System.out.println("joining "" + s1 + "" and "" + s2 + """);
return s1 + "/" + s2;
};
System.out.println(Stream
.of("a", "b", "c", "d", "e", "f")
.parallel()
.reduce("", accumulator)
);
This is example output (it differs between runs):
joining "" and "d"
joining "" and "f"
joining "" and "b"
joining "" and "a"
joining "" and "c"
joining "" and "e"
joining "/b" and "/c"
joining "/e" and "/f"
joining "/a" and "/b//c"
joining "/d" and "/e//f"
joining "/a//b//c" and "/d//e//f"
/a//b//c//d//e//f
You can add an if statement to your function to handle empty string separately:
System.out.println(Stream
.of("a", "b", "c", "d", "e", "f")
.parallel()
.reduce((s1, s2) -> s1.isEmpty()? s2 : s1 + "/" + s2)
);
As Marko Topolnik noticed, checking s2
is not required as accumulator doesn't have to be commutative function.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…