Closed
Description
The following code is a test of generating and using java.util.Spliterator to create a java.util.stream.Stream:
package xp
import java.util.Spliterator
import java.util.function.Consumer
class Aspi(a: Array[String], private val i0: Int, private var i1: Int) extends Spliterator[String] {
private var i = i0
def characteristics = Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE
def estimateSize = i1-i
override def getExactSizeIfKnown = i1-i
def tryAdvance(f: Consumer[_ >: String]): Boolean = {
println(s"Trying at $i [$i0, $i1)")
if (i >= i1) false
else { f.accept(a(i)); i += 1; true }
}
def trySplit(): Aspi = {
if (i1-i < 4) {
println(s"Could not split [$i $i1)")
null
}
else {
println(s"Splitting from [$i $i1)")
val child = new Aspi(a, (i+i1+1)/2, i1)
i1 = child.i0
child
}
}
}
object Test { def main(args: Array[String]) {
def nu = new xp.Aspi(Array("one", "two", "three", "four", "five"), 0, 5)
val st = java.util.stream.StreamSupport.stream(nu, true)
val c = new java.util.Comparator[String]{ def compare(s: String, t: String) = s compareTo t }
println(st.map[String]((s: String) => s + s).max(c))
This compiles and runs successfully. However, when the contents of main
are entered in the REPL, the last line hangs. Stack trace:
"ForkJoinPool.commonPool-worker-1" #14 daemon prio=5 os_prio=0 tid=0x00007f966855f800 nid=0x721f in Object.wait() [0x00007f964a18b000]
java.lang.Thread.State: RUNNABLE
at $line6.$read$$iw$$iw$$anonfun$1.apply(<console>:11)
at $line6.$read$$iw$$iw$$anonfun$1.apply(<console>:11)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at xp.Aspi.tryAdvance(Test.scala:14)
at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
...
Explicitly creating the SAM like so:
println(st.map[String](new java.util.function.Function[String, String] {
def apply(s: String) = s + s
}).max(c))
solves the issue. (Note: I have not tried this on 2.11.5; I assumed 2.12.x was up to date in anything relevant.)