Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

Sorting data is a fundamental operation in all programming languages, allowing for efficient organization and retrieval of information.

Besides, the Map interface is widely used to store key-value pairs in Java. However, the default iteration order of a Map isn’t always conducive to the needs of an application. Often, optimizing our operations requires us to sort the data in a specific order.

In this tutorial, we’ll explore the process of sorting a Java Map by key and value in descending order, offering detailed explanations and practical examples.

2. Understanding Maps and Sorting

A Map in Java is an interface representing a collection of key-value pairs. While the data isn’t inherently ordered, sometimes we need to display or process it in a sorted manner.

When sorting a Map in descending order by values, we need to consider the values associated with each key.

3. Sorting Keys of a Map With TreeMap

The TreeMap class is a sorted implementation of the SortedMap interface in Java. Specifically, it sorts keys of the elements based on their natural ordering or based on a specified Comparator in the constructor:

Map<K, V> sortedMap = new TreeMap(Comparator.reverseOrder());

To proof the previous statement we created a JUnit with an unsorted Map and giving a custom comparator to the constructor of the TreeMap.

@Test
public void given_UnsortedMap_whenUsingTreeMap_thenKeysAreInDescendingOrder() {
    SortedMap<String, Integer> treeMap = new TreeMap<>(Comparator.reverseOrder());
    treeMap.put("one", 1);
    treeMap.put("three", 3);
    treeMap.put("five", 5);
    treeMap.put("two", 2);
    treeMap.put("four", 4);

    assertEquals(5, treeMap.size());
    final Iterator<String> iterator = treeMap.keySet().iterator();
    assertEquals("two", iterator.next());
    assertEquals("three", iterator.next());
    assertEquals("one", iterator.next());
    assertEquals("four", iterator.next());
    assertEquals("five", iterator.next());
}

As we can see the Map is sorted by their keys in the alphabetic order.

4. Sorting Values With Custom Comparator

To sort a Map in descending order, we can use a custom Comparator that reverses the natural order of the values. Here’s an example of how to achieve this:

public static <K, V extends Comparable<? super V>> Map<K, V> sortMapByValueDescending(Map<K, V> map) {
    return map.entrySet()
      .stream()
      .sorted(Map.Entry.<K, V>comparingByValue().reversed())
      .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}

In this example, we define a method sortMapByValueDescending method that takes an input map and creates a custom Comparator to compare Map. Entry objects based on their values in descending order and initializes a new LinkedHashMap to hold the sorted entries.

The method streams through the input map’s entries, sorts them using the Comparator, and populates the sorted entries into the new map using the forEach method. It will result a map, with entries sorted by values in descending order while maintaining key-value associations.

To ensure the correctness of our sorting implementation, we can employ JUnit tests. JUnit is a widely used testing framework for Java applications.

Let’s create some test cases to validate our sortMapByValueDescending method:

@Test
    public void given_UnsortedMap_whenSortingByValueDescending_thenValuesAreInDescendingOrder() {
        Map<String, Integer> unsortedMap = new HashMap<>();
        unsortedMap.put("one", 1);
        unsortedMap.put("three", 3);
        unsortedMap.put("five", 5);
        unsortedMap.put("two", 2);
        unsortedMap.put("four", 4);

        Map<String, Integer> sortedMap = sortMapByValueDescending(unsortedMap);

        assertEquals(5, sortedMap.size());
        final Iterator<Integer> iterator = sortedMap.values().iterator();
        assertEquals(5, (int) iterator.next());
        assertEquals(4, (int) iterator.next());
        assertEquals(3, (int) iterator.next());
        assertEquals(2, (int) iterator.next());
        assertEquals(1, (int) iterator.next());
    }

Here, we create a test method to verify the correctness of our sorting method. Moreover, we define an unsorted Map with various key-value pairs and then check if the sorted Map produced by our method has the correct size and all the elements from the map are sorted.

5. Conclusion

Sorting a Java Map in descending order is a valuable skill for programmers working with key-value data. Based on what we want to sort we can achieve this goal be using a proper Map with a custom Comparator or to create our own Comparator to sort the elements by value. Using TreeMap you will be able to sort the elements of a map by key, writing a custom Comparator you can define which elements do you want to sort keeping the same key-value association. Remember that smooth transitions are essential for guiding readers through your code and explanations, enhancing overall readability.

Armed with this knowledge, we can confidently sort Java Map objects in descending order to optimize our applications.

As always, the complete code samples for this article can be found over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
3 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.