La inferencia del tipo Java lambda no funciona como se esperaba en Kotlin

¿Por qué esta parte del código de Java no se comstack en Kotlin sin el parámetro de tipo explícito en Collectors.toList<String>() ? ¿Hay una manera más idiomática de hacer esto?

 // 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>()) 

¿Por qué esta parte del código de Java no se comstack en Kotlin sin el parámetro de tipo explícito en Collectors.toList<String>() ?

Esto parece un error de compilation para mí. Recomiendo crear un problema en Kotlin (KT) | YouTrack .

¿Hay una manera más idiomática de hacer esto?

Sí. Como comenta Kirill Rakhman , "Kotlin tiene su propio método de extensión File.walk ". p.ej:

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

Si prefiere usar flujos de Java 8, compruebe Kotlin / kotlinx.support: Extensión y funciones de nivel superior para usar las funciones de JDK7 / JDK8 en Kotlin 1.0 . Define una function Stream<T>.toList() :

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

He encontrado dos forms de hacerlo funcionar sin especificar explícitamente el tipo genérico en ambos lugares.

O puede especificar el tipo completo de variable con covarianza genérica

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

o simplemente puede dejar que Kotlin haga su inferencia de tipo para la variable (parámetro no genérico del método)

 val folders2 = Files.walk(Paths.get(args[0])) .filter { it.toFile().isDirectory } .map { it.toAbsolutePath().toString() } .collect(Collectors.toList<String>()) 
  • Clases de datos en Kotlin
  • ¿Cómo se usa Flowable.generate de Kotlin?
  • Acceso a la function de extensión de Kotlin Campo privado de Java
  • Java -> Conversión de Kotlin con types crudos
  • String :: toByteArray () no se comstack en Kotlin
  • Jinq en Kotlin: ¿cómo convertir lambda en Java Serialized Lambda?
  • ¿Delegación de constructor de Kotlin a la class de datos interna?
  • Kotlin Vertx Type Mismatch encontrado Future <Unit> expected Handler <AsyncResult <Void >>
  • ¿Conversión de Kotlin SAM con una interfaz Java interna privada?
  • Kotlin utiliza la interfaz de callback de Java
  • Llamar a kotlin funciones que son palabras key en java de java?