更新: 此问题现在已在Kotlin 1.0.1(以前是
KT-5190)中修复。无需任何解决。
解决方法
解决方法1:
创建此扩展功能,然后像
.toList()在上一样简单地使用它
Stream:
fun <T: Any> Stream<T>.toList(): List<T> = this.collect(Collectors.toList<T>())
用法:
Files.list(Paths.get(file)).filter { }.toList()这增加了一个更明确的通用参数来
Collectors.toList()调用,防止其仿制药的推理过程中出现的bug(这是有点令人费解了该方法的返回类型
Collector<T,?, List<T>>, eeeks!?! )。
解决方法2:
将正确的类型参数添加到您的调用中,
Collectors.toList<Path>()以避免对该参数的类型推断:
Files.list(Paths.get(file)).filter { }.collect(Collectors.toList<Path>())但是变通办法#1中的扩展功能更可重用且更简洁。
保持懒惰
解决该错误的另一种方法是不收集
Stream。您可以保持懒惰,然后将转换
Stream为Kotlin
Sequence或
Iterator,这是制作a的扩展功能
Sequence:
fun <T: Any> Stream<T>.asSequence(): Sequence<T> = this.iterator().asSequence()
现在,您可以使用
forEach许多其他功能,而仍然
Stream只能懒惰地消费一次。使用
myStream.iterator()是另一种方式,但可能没有的功能
Sequence。
当然,在
Sequence您进行一些处理之后,您可以
toList()或
toSet()可以使用任何其他Kotlin扩展来更改集合类型。
而与此,我想创建一个扩展列表文件,以避免不好的API设计
Paths,
Path,
Files,
File:
fun Path.list(): Sequence<Path> = Files.list(this).iterator().asSequence()
至少从左到右流动得很好:
File(someDir).toPath().list().forEach { println(it) }Paths.get(dirname).list().forEach { println(it) }使用Java 8流的替代方法:
我们可以稍微更改您的代码以获取文件列表,
File而您只需要
toList()在最后使用即可:
file.listFiles().filter { }.toList()要么
file.listFiles { file, name -> }.toList()不幸的是
Files.list(...),您最初使用的会返回a
Stream,并且没有给您使用传统收藏的机会。此更改通过从返回Array或collection的函数开始避免了这种情况。
一般来说:
在大多数情况下,您可以避免Java 8流,而使用本机Kotlin
stdlib函数和Java集合的扩展。实际上,Kotlin确实通过编译时只读和可变接口使用Java集合。但是随后它添加了扩展功能以提供更多功能。因此,您具有相同的性能,但具有更多的功能。
也可以看看:
- 标准Kotlin库中提供了哪些Java 8 Stream.collect等效项?-您会发现使用Kotlin stdlib函数和扩展更为简洁。
- Kotlin集合和扩展功能API文档
- Kotlin Sequences API文档
- Kotlin成语
您应该查看
API参考,以了解stdlib中可用的内容。



