Java Program to Sort a Map By Values

Updated on December 18, 2024
Sort a map by values header image

Introduction

When working with maps in Java, sorting them by their values is a common task that can enhance data readability and organization. Typically, Java's Map interface does not directly support ordering by values, as it mainly focuses on key-based operations. This necessitates creative approaches to achieve such functionality, often involving converting the map into a structure that supports ordering.

In this article, you will learn how to sort a Map by values in Java. Discover different methods to accomplish this task, including using a Stream combined with comparators and transforming the map into a list of entries for sorting. Each section provides practical code examples to illustrate the execution of these methods, ensuring you can confidently apply them to your own projects.

Sorting Using Stream API

Basic Sorting of a Map using a Stream

  1. Convert the Map into a Stream of its entries.

  2. Sort the Stream by comparing the Map values.

  3. Collect the results into a new LinkedHashMap to preserve the sorted order.

    java
    import java.util.*;
    import java.util.stream.Collectors;
    
    Map<String, Integer> unsortedMap = new HashMap<>();
    unsortedMap.put("Apple", 10);
    unsortedMap.put("Orange", 5);
    unsortedMap.put("Banana", 7);
    
    Map<String, Integer> sortedMap = unsortedMap.entrySet()
        .stream()
        .sorted(Map.Entry.comparingByValue())
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            Map.Entry::getValue,
            (oldValue, newValue) -> oldValue, LinkedHashMap::new
        ));
    
    sortedMap.forEach((key, value) -> System.out.println(key + ": " + value));
    

    This code snippet sorts the unsortedMap by its values in ascending order. The sorted(Map.Entry.comparingByValue()) handles the sorting operation. Finally, the results are collected into a LinkedHashMap to preserve the order of insertion, which is now sorted by value.

Advanced Sorting with Custom Comparator

  1. Integrate a custom comparator for custom sorting, such as descending order.

  2. Use the same Stream conversion to sort the entries.

  3. Collect the entries back to a map that maintains the order.

    java
    Map<String, Integer> customSortedMap = unsortedMap.entrySet()
        .stream()
        .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            Map.Entry::getValue,
            (e1, e2) -> e1, LinkedHashMap::new
        ));
    
    customSortedMap.forEach((key, value) -> System.out.println(key + ": " + value));
    

    This variation adds a .reversed() to the comparator, sorting the map in descending order based on the values. The rest of the flow remains the same, ensuring the map is collected in a LinkedHashMap to maintain the order.

Sorting with TreeSet and Comparator

Using TreeSet to Sort and Store Map Entries

  1. Use a TreeSet initialized with a custom Comparator based on Map values.

  2. Insert all Map entries into the TreeSet.

  3. Extract a sorted Map from the TreeSet entries.

    java
    Comparator<Map.Entry<String, Integer>> valueComparator = (e1, e2) -> e1.getValue().compareTo(e2.getValue());
    Set<Map.Entry<String, Integer>> sortedEntries = new TreeSet<>(valueComparator);
    sortedEntries.addAll(unsortedMap.entrySet());
    
    // Creating the LinkedHashMap from TreeSet
    Map<String, Integer> treeMapSorted = sortedEntries.stream()
        .collect(Collectors.toMap(
            Map.Entry::getKey,
            Map.Entry::getValue,
            (e1, e2) -> e1, LinkedHashMap::new
        ));
    
    treeMapSorted.forEach((key, value) -> System.out.println(key + ": " + value));
    

    Here, the strategy involves using a TreeSet with a Comparator that sorts the entries as they are added. The TreeSet maintains the natural sorting order as defined by the comparator. The sorted entries are then streamed and collected into a LinkedHashMap to retain the order in the map.

Conclusion

Sorting a Map by its values in Java requires transformining the map data into a form that supports sorting, such as streams or sets. The techniques discussed—utilizing the Stream API for direct sorting and using a TreeSet for custom ordering—provide robust solutions to handle various sorting requirements. Apply these methods effectively in your programming tasks to manage and organize map entries based on their values, thus facilitating better data manipulation and presentation in your applications.