0

I have a list of objects of "Category" class:

    public class Category {
    
        private String originalId;
        private Double ordinal;
        private String sportId;
        private String sportName;
        private String type;
        private String version;
}

And a list of objects of "League" class:

public class League {

    private String leagueName;
    private String originalId;
    private int rank;

    public League(String name, String originalId, int rank) {
        this.leagueName = name;
        this.originalId = originalId;
        this.rank = rank;
    }

These classes are describing the same entitities (so "originalId" field value of "Category" class is equal to "originalId" field value of "League" class), but values for them are taken from different sources, that's why they were separated from the beginning

What I need to do, is to sort a "Category" list by "rank" field value from "League" class

So, logic of sorting should be as following:

  1. For each "Category" object, I will try to find a corresponding "League" object, by comparing their "originalId" field

  2. if there is a corresponding object found, then take a value of "rank" field from "League" object and use it for sorting a list of "Category" objects by rank

  3. if there is no corresponding object found, then such "Category" object should be moved to the end of a list during sorting

So, a comparator should be like this:

public static Comparator<Category> byRank() {
        return nullsLast(comparing(Category::getRankFromCorrespondingLeagueObject, nullsLast(naturalOrder())));
    }

And this is where I stumped, because it is unusual for me to use a field value, taken from another object, for using it while sorting

Is there some simple nice approach to doing so ?

1 Answer 1

2

Create a map of League ranks by originalId, supply it to your comparator and use it. If you can't find anything in a map then set use Integer.MIN_VALUE (or MAX_VALUE, depending on which way you fant to order). This would order it to the end of the result. Something like (a bit pseudo code):

public static Comparator<Category> byRank(Map<String, Integer> leagueRanks) {
    return new Comparator<Category>() {
      @Override
      public int compare(Category o1, Category o2) {
        return Integer.compare(leagueRanks.getOrDefault(o1.getOriginalId(), Integer.MAX_VALUE), leagueRanks.getOrDefault(o2.getOriginalId(), Integer.MAX_VALUE));
      }
    };
}

To collect League ranks to map you can use something like this:

Map<String, Integer> leagueRanks = leagues.stream().collect(Collectors.toMap(it -> it.getOriginalId(), it -> it.getRank()));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.