Is there are a sort method that would take multiple comparators and use them in case the sort order is same for a list of elements?

the_way :

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

  1. Sort Offers based on offerScore.--> List

  2. Take out offers with same score from Step 1.--> List

  3. Sort Offers from Step 2 based on last Date and or Offer Value. --> List

  4. Add back List from Step 3 to List in Step 1.--> List

  5. 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!!

Andrew Tobilko :

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)

UPDATE

Comparator<Offer> comparator =
// OfferScore -> DESC
Comparator.comparingInt(Offer::getOfferScore).reversed()
// Dates -> ASC
.thenComparing(Offer::getLastDate)                    
// Value -> DESC   
.thenComparing(Comparator.comparingInt(Offer::getOfferScore).reversed());

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=139403&siteId=1