Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Comparator.comparing() function work?

For the code below:

ForComparatorDemo object1 = new ForComparatorDemo("object-1",5);
ForComparatorDemo object2 = new ForComparatorDemo("object-2",4);
ForComparatorDemo object3 = new ForComparatorDemo("object-3",3);
ForComparatorDemo object4 = new ForComparatorDemo("object-4",4);

List<ForComparatorDemo> objectList = new ArrayList<>();
objectList.add(object1);
objectList.add(object2);
objectList.add(object3);
objectList.add(object4);
Comparator<ForComparatorDemo> comparer = Comparator.comparing(ForComparatorDemo::getAge);
objectList.sort(comparer);
objectList.forEach(object -> System.out.println(object.getName() + " " + object.getAge()));

I got this output(which is correct):

object-3 3

object-2 4

object-4 4

object-1 5

The question is how did that comparing function actually work? After digging into documentation I found this code for Coamparator.comparing(..) function :

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

Could you explain me how is this function getting these two values (c1 and c2) and how that return statement actually works?

like image 340
Milind Vinkar Avatar asked Oct 19 '22 06:10

Milind Vinkar


1 Answers

Method comparing() does not compare things.

It returns new Comparator, which is described as lamda. This is possible, as Comparator interface is FunctionalInterface.

So, this code

(Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));

is equivalent of:

new Comparator<T>() {
    int compare(T c1, T c2) {
        return keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    } 
}

So c1 and c2 are names of arguments.

Items are compared by key, which is extracted by keyExtractor Function.

Actual object are passed into compare() method from places, where comparator are actually used. Usually, these are different sorting methods where all collection values are iterated through via loop or iterator and compared to each other on to some outer value. For example, you could check Arrays.mergeSort.

like image 200
arghtype Avatar answered Oct 31 '22 21:10

arghtype