简体   繁体   中英

How to use multiple Comparators on a Map and value properties with Java 8

I have a Map and need to sort the Key based on multiple conditions. How to achieve this using Java 8 Comparator and Stream?

class MyObject {
    private Set<Objects> setOfStuff;
    public Set<Objects> getSetOfStuff(){
        return listOfStuff;
    }
    public int countStuff(){
        return listOfStuff.size();
    }
}

Map<String, List<MyObject> needsSorting = new HashMap<>();
needsSorting.put("Monday", createSetOfObj());
needsSorting.put("Wednesday", createSetOfObj());
needsSorting.put("Thursday", createSetOfObj());

Set<MyObject> createSetOfObj() {
...
    return list;
}

Map<String, Set<MyObject>> sortedResult = new LinkedHashMap<>();
  1. Sort on Key, alphabetically
  2. Sort key based on size of List<MyObject>
  3. Sort Key based on size of the largest MyObject countStuff();

if not, it there a better approach?

Update 1:

I think I have 1 & 2 done. Just not sure about how to do 3.

Comparator<Entry<String, List<MyObject>>> comparator = Comparator.comparing(Map.Entry<String, List<MyObject>>::getKey)
            .thenComparingInt(e -> e.getValue().size());

Update 2:

This seems to be producing the comparison I needed. I added a countStuff for easy size access.

Comparator<Entry<String, Set<MyObject>>> comparator = Comparator.comparing(Map.Entry<String, Set<MyObject>>::getKey)
            .thenComparingInt(e -> e.getValue().size())
            .thenComparingInt(e -> e.getValue().stream().map(MyObject::countStuff).max(Integer::max).get());

The HashMap is not ideal for sorting, you could use a TreeMap instead, and pass your comparator to the constructor:

SortedMap<String, List<MyObject>> sorted = new TreeMap<>(comparator);

Edit : the comparator only works for keys not values

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM