Reputation: 21606
I have the following example:
public class Utils{
public static int compareByLength(String s1, String s2)
{
return s1.length() - s2.length();
}
}
Arrays.sort(srt,Utils::compareByLength);
I understand reference methods in Java8 and I understand the sorting condition here.
What I don't understand is how under the hood Sort works. It accepts the static method: 'compareByLength' and knows how to translate the Strings s1,s2 as it's comparators variables.
I understand that Array.sort takes the second param as: Comparator<? super T> c
But still was hard for me to understand how it takes the function compareByLength
and actually "understanding" the comparator criteria.
Thanks, ray.
Upvotes: 0
Views: 183
Reputation: 124235
Arrays.sort
method code looks like
public static <T> void sort(T[] a, Comparator<? super T> c) {
if (c == null)
c = NaturalOrder.INSTANCE;
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
so based on arguments, it uses sorting algorithms like in this case merge sort or tim sort passing to them array you want to sort and Comparator which should be used to decide how elements should be sorted (in case comparator will not be passed default one NaturalOrder.INSTANCE
will be used).
Since Comparator
is functional interface because it has only one abstract method
int compare(T o1, T o2);
we can use method reference Utils::compareByLength
which is same as using lambda
(String s1, String s2) -> Utils.compareByLength(s1,s2)
so it is almost the same as passing instance of anonymous inner class which extends Comparator<String>
interface and implements its compare
method using body of lambda. So your code is similar to
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return Utils.compareByLength(s1, s2);
}
});
Now general contract is that Comparator#compare(value1, value2)
returns
This criteria are used in implementations of sorting algorithms so regardless if it is used merge sorting, quick sort or tim sort contract stays the same. Now each of this sorting algorithms can use comparator passed in sort
method which in your case is Comparator which thanks to Lambdas or more precisely method reference is using Utils.compareByLength
method to decide it two elements are suppose to be switched or not.
Upvotes: 2
Reputation:
It's just returning the difference between the two lengths. You're going to end up with a negative number, or a positive one (in which case one or the other of the two variables should come first in the sort order) or the lengths are the same, meaning you'll get a zero. That's it. If you swap around the two numbers involved in the subtraction you'll see that you switch the sort order (ie from ascending to descending). This comparison is applied to all of the numbers involved in the sort by the java sort method.
You could compare strings, or sizes of buffers, or what have you, in that method, depending on what you're sorting (ie strings, classes etc). You could put logic there to first do the subtraction, and it's that's 0 then the tie breaker could be to check some other variable. But you're always going to have to return a number which is positive, negative or zero, which tells the algorithm doing the sort which of the two parameters being compared is the "winner".
Upvotes: 0