Android開発でKotlinを書いている中で「find
firstOrNull
singleOrNull
って同じじゃね?」と思ったので調べました。
TL;DR
-
find
とfirstOrNull
は同じ挙動なので好きな方を使えばOK -
singleOrNull
は該当する要素が1つのみであることを確認したい場合に使うのが良さそう
動かしてみる
サンプル:https://pl.kotl.in/0WB5a4Efr
find
fun find() {
val numbers = listOf(0, 1, 2, 3, 4, 4)
val four = numbers.find { it == 4 }
println(four)
val five = numbers.find { it == 5 }
println(five)
}
結果
4
null
firstOrNull
fun firstOrNull() {
val numbers = listOf(0, 1, 2, 3, 4, 4)
val four = numbers.firstOrNull { it == 4 }
println(four)
val five = numbers.firstOrNull { it == 5 }
println(five)
}
結果
4
null
singleOrNull
fun singleOrNull() {
val numbers = listOf(0, 1, 2, 3, 4, 4)
val four = numbers.singleOrNull { it == 4 }
println(four)
val five = numbers.singleOrNull { it == 5 }
println(five)
}
結果
null
null
実装
find
@kotlin.internal.InlineOnly
public inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T? {
return firstOrNull(predicate)
}
find
はfirstOrNull
のエイリアスだった
firstOrNull
public inline fun <T> Iterable<T>.firstOrNull(predicate: (T) -> Boolean): T? {
for (element in this) if (predicate(element)) return element
return null
}
要素を見つけたら返すだけ
singleOrNull
public inline fun <T> Iterable<T>.singleOrNull(predicate: (T) -> Boolean): T? {
var single: T? = null
var found = false
for (element in this) {
if (predicate(element)) {
if (found) return null
single = element
found = true
}
}
if (!found) return null
return single
}
該当する要素が2つ以上ある場合null
を返す
いかがでしたか?
find
はfirstOrNull
のエイリアスだったんですね〜
この3つのメソッドのうち、singleOrNull
は若干挙動が違うもののそこまで違いを意識して使わなくて良さそうでした。
このテーマについてはStack OverflowやKotlinコミュニティでも議論されているようなので興味のある方は見てみるといいかもしれません。