Binary search is not restricted to List<Int>
. We can perform Binary search on list of objects of any class. To sort list of objects, we have to pass an additional parameter - comparator
:
public fun <T> List<T>.binarySearch(
element: T,
comparator: Comparator<in T>,
fromIndex: Int = 0,
toIndex: Int = size
): Int
Lets see an example of generic Binary Search and then understand what a Comparator is.
Following is an example of Binary Search on List<Planet>
:
class Planet(
val name: String,
val mass: Double,
val radius: Double,
val distanceFromSun: Double
)
fun main() {
val planets = listOf(
Planet("Earth", 5.9724e24, 6371.0, 149.6e6),
Planet("Jupiter", 1.8982e27, 69911.0, 778.6e6),
Planet("Mars", 6.4171e23, 3389.5, 227.9e6),
Planet("Mercury", 3.3011e23, 2439.7, 57.91e6),
Planet("Neptune", 1.0243e26, 24622.0, 4.50e9),
Planet("Pluto", 1.3030e22, 1188.3, 5.91e9),
Planet("Saturn", 5.6834e26, 58232.0, 1.43e9),
Planet("Uranus", 8.6810e25, 25362.0, 2.87e9),
Planet("Venus", 4.8675e24, 6051.8, 108.2e6)
)
val mars = Planet("Mars", 6.4171e23, 3389.5, 227.9e6)
val index = planets.binarySearch(mars, compareBy { it.name })
if (index < 0) {
println("${mars.name} was not found in the list.")
} else {
println("${mars.name} was found at index $index in the list.")
}
}
Note that we have used the compareBy()
function to define a comparator for Planet.
Comparator is an interface that needs to be implemented for comparing two objects of same type :
public expect fun interface Comparator<T> {
public fun compare(a: T, b: T): Int
}
To implement the Comparator interface, we can use the built-in compareBy()
function :
public fun <T> compareBy(
selector: (T) -> Comparable<*>?
): Comparator<T>
selector
is a lambda to return the value based on which the comparison has to be performed.
Usage :
planets.binarySearch(mars, compareBy { it.name })