2

为什么这段 Java 代码在没有显式类型参数的情况下无法在 Kotlin 中编译Collectors.toList<String>()?有没有更惯用的方法来做到这一点?

// works
List<String> 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<in String!>..List<Any?>?` which is not compatible to `List<String>`
val folders: List<String> = Files.walk(Paths.get(args[0]))
            .filter { it.toFile().isDirectory }
            .map { it.toAbsolutePath().toString() }
            .collect(Collectors.toList())

// compiles
val folders: List<String> = Files.walk(Paths.get(args[0]))
            .filter { it.toFile().isDirectory }
            .map { it.toAbsolutePath().toString() }
            .collect(Collectors.toList<String>())
4

2 回答 2

3

为什么这段 Java 代码在没有显式类型参数的情况下无法在 Kotlin 中编译Collectors.toList<String>()

对我来说,这看起来像是一个编译器错误。我建议在Kotlin (KT)中创建一个问题| 你跟踪

有没有更惯用的方法来做到这一点?

是的。正如Kirill Rakhman 评论的那样,“Kotlin 有自己的File.walk扩展方法。” 例如:

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

如果您更喜欢使用 Java 8 流,请查看 Kotlin/kotlinx.support:扩展和顶级函数以使用 Kotlin 1.0 中的 JDK7/JDK8 功能。它定义了一个Stream<T>.toList()函数:

val folders: List<String> = Files.walk(Paths.get(args[0]))
        .filter { it.toFile().isDirectory }
        .map { it.toAbsolutePath().toString() }
        .toList()
于 2016-08-22T14:52:31.193 回答
0

I've found two ways to make it work without explicitly specifying generic type in both places.

Either you can specify full type of variable with generic covariance

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

or you can simply let Kotlin do its type inference for variable (not generic parameter of method)

val folders2 = Files.walk(Paths.get(args[0]))
        .filter { it.toFile().isDirectory }
        .map { it.toAbsolutePath().toString() }
        .collect(Collectors.toList<String>())
于 2016-08-22T09:08:04.097 回答