Java 8でjava.util.Collection
に追加されたメソッドとして、Stream
を返すstream()
メソッドがあります。これ、java.util.Collection
に追加されたメソッドなのだから、当然Kotlinでも呼び出せて良いはずですが、実はできません。
>>> val x = listOf(1, 2, 3, 4, 5)
>>> x.stream()
error: unresolved reference: stream
x.stream()
^
Scalaでは何の問題もなくできます(なお、SAM Type変換を行っているので、Scala 2.12以降でのコードです)。
scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._
scala> val x = List(1, 2, 3, 4, 5).asJava
x: java.util.List[Int] = [1, 2, 3, 4, 5]
scala> x.stream()
res0: java.util.stream.Stream[Int] = java.util.stream.ReferencePipeline$Head@3739f3c9
scala> x.stream().filter{e => e % 2 == 0}
res1: java.util.stream.Stream[Int] = java.util.stream.ReferencePipeline$2@59371066
さて、何故、このような差が生まれてしまったのでしょうか。KotlinではJavaのコレクション・フレームワークを、実装上は再利用しつつ、型としては違う振る舞いを与えているからです。そのため、無理やりjava.util.Collection
にキャストしてやると、stream()メソッドが呼び出せるというめんどくさい挙動になっています。
>>> val x = listOf(1, 2, 3, 4, 5)
>>> (x as java.util.Collection<Int>).stream()
java.util.stream.ReferencePipeline$Head@15d0c81b
>>> (x as java.util.Collection<Int>).stream().filter{it % 2 == 0}
java.util.stream.ReferencePipeline$2@587c290d
よーするにKotlinのコレクションはJavaのコレクションだといいながら、型としてはJavaのコレクションだと思って扱うと上手くいかないという悲しい例です。
JavaとinteroperableじゃないKotlinの悲しい一面です。
ところで、
kotlinlang.org
をみると、
Kotlin supports Java 8 streams, which provide similar functionality
と書いてありますが、こういうのをみると、どこがやねん(何故か関西弁っぽい)とツッコミたくなります。