Java lambdatypes推断在Kotlin中没有像预期的那样工作

为什么在没有Collectors.toList()的显式types参数的情况下,这段Java代码不能在Kotlin中编译? 有没有更习惯的方式来做到这一点?

 // works List folders = Files.walk(Paths.get(args[0]))     .filter(it -> it.toFile().isDirectory())      .map(it -> it.toAbsolutePath().toString())      .collect(Collectors.toList()); // does not compile - resulting type is `MutableList..List?` which is not compatible to `List` val folders: List = Files.walk(Paths.get(args[0]))      .filter { it.toFile().isDirectory }      .map { it.toAbsolutePath().toString() }      .collect(Collectors.toList()) // compiles val folders: List = Files.walk(Paths.get(args[0]))      .filter { it.toFile().isDirectory }      .map { it.toAbsolutePath().toString() }      .collect(Collectors.toList()) 

为什么在没有Collectors.toList()的显式types参数的情况下,这段Java代码不能在Kotlin中编译?

这看起来像一个编译器的bug。 我建议在Kotlin(KT)|中创建一个问题 YouTrack 。

有没有更习惯的方式来做到这一点?

是。 正如Kirill Rakhman 所说 :“Kotlin有自己的File.walk扩展方法。” 例如:

 val folders: List = File(args[0]).walk() .filter(File::isDirectory) .map(File::getAbsolutePath) .toList() 

如果您更喜欢使用Java 8流,请检查Kotlin / kotlinx.support:扩展function和顶级function以使用Kotlin 1.0中的JDK7 / JDK8function 。 它定义了Stream.toList()函数:

 val folders: List = Files.walk(Paths.get(args[0])) .filter { it.toFile().isDirectory } .map { it.toAbsolutePath().toString() } .toList() 

我发现有两种方法可以使它在两个地方都没有明确指定generics的情况下工作。

您可以指定具有通用协方差的完整types的variables

 val folders: MutableList = Files.walk(Paths.get(args[0])) .filter { it.toFile().isDirectory } .map { it.toAbsolutePath().toString() } .collect(Collectors.toList()) 

或者你可以简单地让Kotlin对variables进行types推断(不是方法的通用参数)

 val folders2 = Files.walk(Paths.get(args[0])) .filter { it.toFile().isDirectory } .map { it.toAbsolutePath().toString() } .collect(Collectors.toList())