我需要映射一个列表并检索第一个非空元素,并且我需要像Java 8 streams API中那样对map操作进行短路。在没有Java 8流的Kotlin中,有现成的方法可以这样做吗?
为此,我创建了自己的扩展方法:
fun <T, R> Iterable<T>.firstNonNullMapping(transform: (T) -> R?): R? {
for (element in this) {
val result = transform(element)
if (result != null) {
return result
}
}
return null
}一次测试证明这是可行的。
val firstNonNullMapping = listOf(null, 'a', 'b')
.firstNonNullMapping {
assertNotEquals(it, 'b') // Mapping should be stopped before reaching 'b'
it
}
assertEquals(firstNonNullMapping, 'a')然而,IntelliJ建议我将for循环替换为更整洁的
return this
.map { transform(it) }
.firstOrNull { it != null }问题是,这将映射可迭代的所有元素,对于我的用例来说,它是必不可少的,即在第一个非空元素处停止。
发布于 2017-01-13 10:03:31
Kotlin懒洋洋地计算了对应于Java 8流的序列,而不是在集合上调用stream(),而是调用asSequence()。
return this
.asSequence()
.mapNotNull { transform(it) }
.firstOrNull()发布于 2021-06-15 00:22:03
Kotlin1.5为.asSequence()、.mapNotNull { ... }和.first/firstOrNull()组合提供了一个快捷的替代方法:函数firstNotNullOf和firstNotNullOfOrNull。
它们对每个元素执行一次transform函数,并在遇到该函数的第一个非空结果时立即停止,因此它们处于短路状态。
发布于 2017-01-13 10:56:21
我想知道什么更快,@ingoKegel的解决方案,或者这个:
return this.firstOrNull { transform(it) != null }?.let { transform(it) }https://stackoverflow.com/questions/41631856
复制相似问题