I have a list of Offers to be given out. Each offer has a score, last date and offer value associated with it. I want these offers to be sorted on offer Score. This was simple to do using Collections.sort(..).
Now, if the offers have same score, i want to sort on last date. If the last dates is also same, I want to sort on Offer value.
I have written datesComparator and ValueComparator for this.
Then I did the following which is quite expensive
Sort Offers based on offerScore.--> List
Take out offers with same score from Step 1.--> List
Sort Offers from Step 2 based on last Date and or Offer Value. --> List
Add back List from Step 3 to List in Step 1.--> List
For Step 4 , use sort on offer score again, since sort method doesn't change the order of offers with same score.
I was wondering if there's a simpler method that would take up multiple comparators and then the sort would take up next comparator in case the result of first comparator is same for consecutive offers!!
You are looking for Comparator.thenComparing
.
Returns a lexicographic-order comparator with another comparator. If this
Comparator
considers two elements equal, i.e.compare(a, b) == 0
,other
is used to determine the order.
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
For instance,
Comparator<Offer> comparator =
Comparator.comparingInt(Offer::getOfferScore)
.thenComparing(Offer::getLastDate)
.thenComparingInt(Offer::getOfferScore);
(assuming these methods exist)
Comparator<Offer> comparator =
// OfferScore -> DESC
Comparator.comparingInt(Offer::getOfferScore).reversed()
// Dates -> ASC
.thenComparing(Offer::getLastDate)
// Value -> DESC
.thenComparing(Comparator.comparingInt(Offer::getOfferScore).reversed());
The java.util.Comparator
interface has all methods you need to chain comparisons together. So your code may look something like this:
List<Offer> offers = getOffers();
offers.sort(Comparator
.comparing(Offer::getOfferScore)
.thenComparing(Offer::getOfferValue)
.thenComparing(Offer::getLastDate);
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