How to sort HashMap entries values by multiple properties Java8

You can use the following comparator for sorting:

Comparator
        .comparingLong(UserMetrics::getParam1)
        .thenComparingLong(UserMetrics::getParam2);

The difficulty is, however that you want to sort values, not keys. It seems also you need both keys and values. For this you could make and sort a copy of the entry set of your map. Something along the lines:

List<Map.Entry<String, UserMetrics>> sortedEntries = new ArrayList<>(map.entrySet());
Collections.sort(sortedEntries,
    Map.Entry.comparingByValue(
        Comparator
            .comparingLong(UserMetrics::getParam1)
            .thenComparingLong(UserMetrics::getParam2)));

Alternatively you can also use a sorted collection (like TreeSet) or a sorted stream - normally you can provide your own comparator to the "sorting things".

Also note that I'm using comparingLong/thenComparingLong, unlike other answers where people just used comparing/thenComparing. The problem with comparing/thenComparing is that if you have primitive types like long, comparing/thenComparing will essentially box them into wrapper types like Long, which is totally unnecessary.


You can use below code. I have written by using Employee the s value object, so you can use your own Object :

public class Main {
    public static void main(String[] args) throws InterruptedException {
        HashMap<String, Employee> map = new HashMap<>();
        Map<String, Employee> sortedMap = map.entrySet()
                                             .stream()
                                             .sorted(Entry.comparingByValue(Main::compare))
                                             .collect(Collectors.toMap(Entry::getKey, Entry::getValue,
                                                     (e1, e2) -> e1, LinkedHashMap::new));

    }

    public static int compare(Employee e1, Employee e2) {
        return e1.getAge() - e2.getAge();
    }
}

Edited: Here is another way you can use Comparator#comparing and thenComparing to sort.

Map<String, Employee> sortedMap = map.entrySet()
                                     .stream()
                                     .sorted(Entry.comparingByValue(
                                             Comparator.comparing(Employee::getAge)
                                                       .thenComparing(Employee::getSalary)))
                                     .collect(Collectors.toMap(Entry::getKey, Entry::getValue,
                                             (e1, e2) -> e1, LinkedHashMap::new));

Tags:

Java

Java 8