Description
Whilst studying the ripples of PR #3396, I discovered two defects in the javalib Colectors#joining
method(s).
-
The first is user visible, albeit hard to provoke: the
combiner.apply(arg1, arg2)
function fail the deliminator
with which the collector was created between arg1 & arg2.
(For the detail oriented, the collector can not be created with a null deliminator, but it can be created with
an empty string as the deliminator. It is hard to distinguish the cases of the empty string not being added
and it having been properly added. Other deliminators are clearly visible to the determined.)Imagine the case of
Collectors.joining("|")
. A currently private test gives the expected results on JVM but
fails on Scala Native:
Test org.scalanative.testsuite.javalib.util.stream.CollectorsTest.collectorsJoining_MergeSN failed:
org.junit.ComparisonFailure: unexpected combined expected:<Left[|]Right> but was:<Left[]Right>
-
The second defect is visible to people wanting to use the
Collector.joining#merge
method. Normally, this
would be either nobody or library writers.Reverse engineering (but not looking at the JDK code) shows that JVM
uses aStringJoiner
for the accumulator A method in[T, A, R]
. Scala Native uses aStringBuilder
.
To be fair (& defensive),StringJoiner
was not available when that code was written.Normally the A methods is abstract and "do not care". In the admittedly abstruse Test mentioned above, the
difference means that the same Test can not be compiled & run on both JVM and Scala Native.Those writing implementations of parallel stream methods, say a parallel
collect()
are likely to use the
combiner
method and encounter difficulties.