Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chain of comparators in java

Reading the Java Tutorial by Oracle on interfaces which gives a example on Card (Playing cards) I was trying to understand the default methods in interfaces. Here's the link, section "Integrating default methods in existing interfaces". Now in the last section they sorted the Cards first by rank and then by suits. Following logics have been given. Assume that whatever interfaces, functions or classes that are used have been defined and sort function takes a Comparator

Logic 1:

package defaultmethods;

import java.util.*;
import java.util.stream.*;
import java.lang.*;

public class SortByRankThenSuit implements Comparator<Card> {
    public int compare(Card firstCard, Card secondCard) {
        int compVal =
            firstCard.getRank().value() - secondCard.getRank().value();
        if (compVal != 0)
            return compVal;
        else
            return firstCard.getSuit().value() - secondCard.getSuit().value(); 
    }
}

Logic 2:

myDeck.sort(
    Comparator
        .comparing(Card::getRank)
        .thenComparing(Comparator.comparing(Card::getSuit)));

Now I am having some problems in understanding the second logic. I read the comparator interfaces and the new static methods which have been included in Java 1.8 . Now I understand something like this myDeck.sort(Comparator.comparing(Card::getRank)) which sorts by rank but after reading the documentation for thenComparing , I am unable to understand how thenComparing returns a Comparator which achieves the above Logic 1. Does it internally build something like the if-else construct as specified in Logic 1 ?

like image 974
abkds Avatar asked Aug 25 '15 03:08

abkds


People also ask

What is Comparator chaining in Java?

A ComparatorChain evaluates every Comparator in the chain as needed. If the current Comparator returns a zero, the next Comparator is invoked until there are no more Comparator objects left in the chain. If the final Comparator returns a zero value, the ComparatorChain returns a zero.

How do comparators work in Java?

Comparator , represents a component that can compare two objects so they can be sorted using sorting functionality in Java. When sorting e.g a Java List you can pass a Java Comparator to the sorting method. The Comparator is then used to compare the objects in the List during sorting.

Where are comparators used in Java?

Java Comparator interface is used to order the objects of a user-defined class. This interface is found in java. util package and contains 2 methods compare(Object obj1,Object obj2) and equals(Object element).

What is Comparator and comparable in Java example?

Comparable interface is used to sort the objects with natural ordering. Comparator in Java is used to sort attributes of different objects. Comparable interface compares “this” reference with the object specified. Comparator in Java compares two different class objects provided. Comparable is present in java.


1 Answers

Yes, it creates internally something similar, just with more intermediate lambdas. Assuming that your getRank and getSuit methods return some instances of comparable classes Rank and Suit, in your case you effectively have:

Function<Card, Rank> toRank = Card::getRank;
Comparator<Card> comp1 = (a, b) -> toRank.apply(a).compareTo(toRank.apply(b));
Function<Card, Suit> toSuit = Card::getSuit;
Comparator<Card> comp2 = (a, b) -> toSuit.apply(a).compareTo(toSuit.apply(b));
Comparator<Card> result = (a, b) -> {
  int res = comp1.compare(a, b);
  return res != 0 ? res : comp2.compare(a, b);
};

So after inlining (which might be performed by JIT-compiler) you may have something like this:

Comparator<Card> result = (a, b) -> {
  int res = a.getRank().compareTo(b.getRank());
  return res != 0 ? res : a.getSuit().compareTo(b.getSuit());
};

Note that you can use the simpler version:

myDeck.sort(
    Comparator
        .comparing(Card::getRank)
        .thenComparing(Card::getSuit));
like image 112
Tagir Valeev Avatar answered Sep 30 '22 07:09

Tagir Valeev