Kotlin短路图{} .firstOrNull {}

Lov*_*ove 5 kotlin

我需要映射一个列表并检索第一个非null元素,我需要将map操作短路,就像它应该在Java 8流API中一样.有没有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
}
Run Code Online (Sandbox Code Playgroud)

测试证明这是有效的

val firstNonNullMapping = listOf(null, 'a', 'b')
        .firstNonNullMapping {
            assertNotEquals(it, 'b') // Mapping should be stopped before reaching 'b'
            it
        }
assertEquals(firstNonNullMapping, 'a')
Run Code Online (Sandbox Code Playgroud)

但是,IntelliJ建议我用更整洁的东西替换我的for循环

return this
        .map { transform(it) }
        .firstOrNull { it != null }
Run Code Online (Sandbox Code Playgroud)

问题是这将映射iterable的所有元素,并且对于我的第一个非null元素停止的用例是必不可少的.

Ing*_*gel 12

Kotlin懒惰地评估了与Java 8流相对应的序列,而不是调用stream()集合,您调用asSequence():

return this
        .asSequence()
        .map { transform(it) }
        .firstOrNull { it != null }
Run Code Online (Sandbox Code Playgroud)

  • `.firstOrNull {it!= null}`与`firstOrNull()`不同.第一个将返回第一个非null元素,如果序列为空,则返回null.后者将返回第一个元素,无论它是否为null(如果它为空,则返回null). (3认同)

Ily*_*lya 11

.asSequence()Kotlin 1.5 提供了、.mapNotNull { ... }和组合的快捷方式替换 .first/firstOrNull():分别是函数 firstNotNullOffirstNotNullOfOrNull

它们对每个元素执行transform一次函数,并在遇到该函数的第一个非空结果时立即停止,因此它们是短路的。