Given the following code extracted from 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) } }
My own solution used customers.find
. Both work in the koan scenario.
The documentation for firstOrNull
and find
seem to be very similar.
What is the difference between these two functions?
firstOrNull( predicate: (UShort) -> Boolean. ): UShort? Returns the first element matching the given predicate, or null if element was not found.
In Kotlin, filtering conditions are defined by predicates – lambda functions that take a collection element and return a boolean value: true means that the given element matches the predicate, false means the opposite.
In this thread from 2014, Kotlin community members and JetBrains staff discuss the merits of the different methods find
and firstOrNull
:
https://youtrack.jetbrains.com/issue/KT-5185
While not an official statement, JetBrains' employee Ilya Ryzhenkov describes it as:
I think we can undeprecate
find
and make it an alias tofirstOrNull
. Much likeindexOf
has well-known semantics,find
is also widely recognised as "find first item matching predicate or return null if nothing is found". People who like precise meaning can usefirstOrNull
,singleOrNull
to express the intent.
In other words:
find(predicate)
and firstOrNull(predicate)
are identical in behaviour and find
can be considered alias of firstOrNull
find
is kept around as an alias because it's more intuitive and discoverable for programmers not already familiar with these Linq-style - or functional - methods.In actuality the definition of Array<out T>.find
is not defined as an alias, but as a wrapper (though the optimizing compiler will inline it, effectively making it an alias):
https://github.com/JetBrains/kotlin/blob/1.1.3/libraries/stdlib/src/generated/_Arrays.kt#L657
@kotlin.internal.InlineOnly public inline fun <T> Array<out T>.find(predicate: (T) -> Boolean): T? { return firstOrNull(predicate) }
Ditto for 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) }
(I'm not a Kotlin user myself, but I'm surprised that these methods are implemented as compile-time generated code manually defined for each collection type instead of as a single JVM generic method - is there some reason for this?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With