等效的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#collectexpression式的返回值在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()) 

然后用它来进行StreamList转换:

 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名称是不同的。