等效的Java和Kotlin Stream代码之间意外的types差异
编辑2016年3月1日:公平的警告:这个问题被问到1.0.0之前的Kotlin。 从Kotlin 1.0.0开始,情况就不一样了。 请参阅下面的@Jayson Minard的Kotlin 1.0.0答案。
在使用Stream的Java 8代码中,我写了类似的东西
public static void main(String... args) { Stream integerStream = Stream.of(1,2,3); List integerList = integerStream.collect(Collectors.toList()); }
但是在Kotlin编写的类似代码中,我得到了意想不到的结果。
public fun main(args: Array) { val integerStream : Stream = Stream.of(1, 2, 3) // this is what I expect to write, like the Java 8 code, but is a compilation error: // "required: java.util.List found: kotlin.MutableList<in kotlin.Int!" // val list : java.util.List = integerStream.collect(Collectors.toList()) // I must instead write this val list : MutableList = integerStream.collect(Collectors.toList()) }
为什么Stream#collect
expression式的返回值在Kotlin代码中与Java代码中的列表types不同? (我猜这是因为Kotlin的一些Java Collections特有的魔法)
你可以在Kotlin 1.0中做到这一点:
val integerStream : Stream = Stream.of(1, 2, 3) val list : List = integerStream.collect(Collectors.toList ())
要么
val integerStream : Stream = Stream.of(1, 2, 3) val list : MutableList = integerStream.collect(Collectors.toList ())
或者不在意,并且让我们推断:
val integerStream = Stream.of(1, 2, 3) val list = integerStream.collect(Collectors.toList())
注意:我将您的toList()
调用更改为toList
以解决https://stackoverflow.com/a/35722167/3679676中提到的问题
你也可以创建一个扩展函数:
fun Stream.toList(): List = this.collect(Collectors.toList ())
然后用它来进行Stream
到List
转换:
val integerStream = Stream.of(1, 2, 3) val list = integerStream.toList() val stringStream = Stream.of("a", "b", "c") val stringList = stringStream.toList()
最后这个例子已经返回List
的只读接口而不是MutableList
。 有关这些与Kotlin中其他映射接口的区别,请参阅Java Interop文档,映射types 。
最后,另一个变体是转换为Sequence
并保持懒惰,因为它是Stream
的Kotlin等价物。
fun Stream.asSequence(): Sequence = this.iterator().asSequence()
或Stream.iterator()
是类似的,但不一样。
我认为这是因为Java中的List
是可变的,默认情况下,在Kotlin中它们是不可变的。 在代码中,你正在使用一个Java特定的实用程序Collectors.toList
,它返回一个Java List
,这个Java List
被Kotlin翻译成一个MutableList
,所以实际上你正在编写相同的代码,只是types名称是不同的。