Files.find() with BiPredicate in Kotlin

≡放荡痞女 提交于 2019-12-29 08:53:07

问题


I want to find all files in files tree. In Java I'd write something like:

try(Stream<Path< paths = Files.find(startingPath, maxDepth,
   (path, attributes) -> !attributes.isDirectory())) {
          paths.forEach(System.out::println);
}

But I am using kotlin, and came up with this:

Files.find(startingPath,maxDepth,
        { (path, basicFileAttributes) -> !basicFileAttributes.isDirectory()}
).use { println(it) }

However, this gives me error:

Cannot infer a type for this parameter. Please specify it explicitly.

Type mismatch:

Required: BiPredicate< Path!, BasicFileAttributes! >!

Found: (???) -> Boolean

Any idea how to use BiPredicate in this case?
Thanks in advance


回答1:


BiPredicate is a Java class, Kotlin function types are not directly compatible. This is due to missing SAM conversions, also explained in my recent answer here.

What you need to pass is an object matcher of type BiPredicate<Path, BasicFileAttributes>. To clarify, something like this:

val matcher = object : BiPredicate<Path, BasicFileAttributes>
{
    override fun test(path: Path, basicFileAttributes: BasicFileAttributes): Boolean
    {
        return !basicFileAttributes.isDirectory()
    }
}

This can be simplified to:

val matcher = BiPredicate<Path, BasicFileAttributes> { path, basicFileAttributes ->
    !basicFileAttributes.isDirectory()
}

When you pass it to Files.find(), Kotlin is even able to infer the generic parameter types. So in total, your expression would be:

Files.find(startingPath, maxDepth, BiPredicate { path, basicFileAttributes ->
    !basicFileAttributes.isDirectory()
}).use { println(it) }



回答2:


You had two problems there. Use BiPredicate { x, y -> code } for the type mismatch error the compiler gives you, and then get the actually do what it intends to do by replacing .use with forEach. Otherwise it prints the stream object.

Files.find(startingPath, maxDepth,
        BiPredicate { path, basicFileAttributes -> !basicFileAttributes.isDirectory() }
).forEach { println(it) }



回答3:


Use FileTreeWalk for more Kotlin-ish way.

File(startingPath).walk()
        .filter { !it.isDirectory }
        .toList()

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.io/-file-tree-walk/index.html



来源:https://stackoverflow.com/questions/51876023/files-find-with-bipredicate-in-kotlin

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!