find和firstOrNull有什么区别?

Kyl*_*yll 16 collections kotlin

鉴于从Kotlin Koans中提取的以下代码:

fun Shop.findAnyCustomerFrom(city: City): Customer? {
    // Return a customer who lives in the given city, or null if there is none
    return customers.firstOrNull { it.isFrom(city) }
}
Run Code Online (Sandbox Code Playgroud)

我用自己的解决方案customers.find.两者都在koan场景中工作.

文档firstOrNullfind似乎非常相似.

这两个功能有什么区别?

Dai*_*Dai 23

在2014年的这个帖子中,Kotlin社区成员和JetBrains工作人员讨论了不同方法的优点,find并且firstOrNull:

https://youtrack.jetbrains.com/issue/KT-5185

虽然不是官方声明,JetBrains的员工Ilya Ryzhenkov将其描述为:

我认为我们可以废弃find并使其成为别名firstOrNull.与indexOf众所周知的语义非常相似,find也被广泛认为是"找到第一项匹配谓词或如果没有找到则返回null".谁喜欢确切含义的人可以用firstOrNull,singleOrNull来表达意图.

换一种说法:

  • find(predicate)并且firstOrNull(predicate)在行为上是相同的,find可以被认为是别名firstOrNull
  • find作为别名保留,因为它对于那些不熟悉这些Linq风格或功能方法的程序员来说更直观,更容易被发现.

实际上,定义Array<out T>.find并未定义为别名,而是作为包装器(尽管优化编译器将内联它,有效地使其成为别名):https:
//github.com/JetBrains/kotlin/blob/1.1.3/库/ STDLIB/SRC /生成/ _Arrays.kt#L657

@kotlin.internal.InlineOnly
public inline fun <T> Array<out T>.find(predicate: (T) -> Boolean): T? {
    return firstOrNull(predicate)
}
Run Code Online (Sandbox Code Playgroud)

同上Sequence<T>.find:https:
//github.com/JetBrains/kotlin/blob/1.1.3/libraries/stdlib/src/generated/_Sequences.kt#L74

@kotlin.internal.InlineOnly
public inline fun <T> Sequence<T>.find(predicate: (T) -> Boolean): T? {
    return firstOrNull(predicate)
}
Run Code Online (Sandbox Code Playgroud)

(我自己不是Kotlin用户,但我很惊讶这些方法是作为编译时生成的代码实现的,这些代码是为每个集合类型而不是单个JVM泛型方法手动定义的 - 这有什么原因吗?)

  • 数组针对Kotlin中的基元进行了优化.指[@ hotkey的回答](/sf/answers/2538462391/). (3认同)