This code basically sorts the array in a descending order:
val arrayList = arrayListOf(1, 5, 2)
Collections.sort(arrayList, object : Comparator<Int> {
override fun compare(x : Int, y: Int) = y - x
})
How in the world does overriding the compare method with y - x
works? How does Kotlin know what y - x
means to put y
before x
if y < x
?
In Kotlin, == is the default way to compare two objects: it compares their values by calling equals under the hood. Thus, if equals is overridden in your class, you can safely compare its instances using ==. For reference comparison, you can use the === operator, which works exactly the same as == in Java.
Using sort() function The sort() function is the recommended way to in-place sort elements of the specified list. The sorting is done according to the natural ordering of its elements. To sort the list in reverse order, switch to the sortDescending() function.
For sorting the list with the property, we use list 's sortedWith() method. The sortedWith() method takes a comparator compareBy that compares customProperty of each object and sorts it. The sorted list is then stored in the variable sortedList .
This actually has nothing to do with Kotlin. It's related to the Java API's Comparator interface, and how Collections.sort uses it.
From the documentation:
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
Now let's try this out for the arguments you gave:
Collections.sort
doesn't know anything about what y - x means. It simply respects the defined contract of the Comparator interface that any implementor also needs to respect (if it wants to work).
It just so happens that y - x
is an implementation that does respect that contract, because Math.
Since Comparator is a SAM interface you can write this code more concise using a lambda:
Collections.sort(arrayList, {x : Int, y: Int -> y - x})
Or even
Collections.sort(arrayList) {
x, y -> y - x
}
since the lambda is the last parameter of the sort
function and the datatype of x
and y
can be inferred.
Taking two objects and having to define a single integer for them is an abstraction of a sort definition. You basically specify in which order those elements would be layed out if sorted.
For sorting integers it might seem like an overkill, but consider having to sort more complex objects for example instances of a class Car
.
This class has a colorCode
and you want to sort by that:
Collections.sort(cars) {
car1, car2 -> car1.colorCode - car2.colorCode
}
That is how you would define an order for those objects in an abstract way.
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