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 ?
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.
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.
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).
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.
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));
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