Sort map by value

This example will demonstrate how to sort a map based on values. In the set up, we will create a map of candy bars keyed by calories and value of the name of the candy bar. Then each snippet will show how to order the hashmap by value. In a comparable example we demonstrate how to sort a dictionary or hashmap by value in groovy.

Setup

Map<Integer, String> CANDY_BARS;

@Before
public void setUp () {
    
    CANDY_BARS = new HashMap<Integer, String>();
    CANDY_BARS.put(233, "REESE'S P-BUTTER CUPS");
    CANDY_BARS.put(222, "REESE'S P-BUTTER CUPS");
    CANDY_BARS.put(284, "TWIX, CARAMEL");
    CANDY_BARS.put(232, "ALMOND JOY");
    CANDY_BARS.put(149, "YORK PEPPERMINT PATTIE");
}

Straight up Java

First creating a java Comparator, this snippet will sort map values in ascending order by passing the comparator to Collections.sort.

@Test
public void sort_map_by_values_java () {
    
    Comparator<Map.Entry<Integer, String>> byMapValues = new Comparator<Map.Entry<Integer, String>>() {
        @Override
        public int compare(Map.Entry<Integer, String> left, Map.Entry<Integer, String> right) {
            return left.getValue().compareTo(right.getValue());
        }
    };
    
    // create a list of map entries
    List<Map.Entry<Integer, String>> candyBars = new ArrayList<Map.Entry<Integer, String>>();
    
    // add all candy bars
    candyBars.addAll(CANDY_BARS.entrySet());
    
    // sort the collection
    Collections.sort(candyBars, byMapValues);
    
    logger.info(candyBars);
    
    assertEquals("ALMOND JOY", candyBars.get(0).getValue());
}

Output

[
    232=ALMOND JOY, 
    222=REESE'S P-BUTTER CUPS, 
    233=REESE'S P-BUTTER CUPS, 
    284=TWIX, CARAMEL, 
    149=YORK PEPPERMINT PATTIE
]

Java 8

This snippet will sort hashmap by value in descending order using java 8. Using a lambda expression we will create a comparator that will compare each entry value. Next calling calling the Stream.sort we will pass the comparator then calling Comparator.reverse.

@Test
public void sort_map_by_values_java8() {

    Comparator<Entry<Integer, String>> byValue = (entry1, entry2) -> entry1.getValue().compareTo(
            entry2.getValue());
    
    Optional<Entry<Integer, String>> val = CANDY_BARS
            .entrySet()
            .stream()
            .sorted(byValue.reversed())
            .findFirst();
    
    logger.info(val);
    
    assertEquals("YORK PEPPERMINT PATTIE", val.get().getValue());
}

Google Guava

First lets define comparator using guava's fluent Ordering utility that will be used in the snippets below.

Ordering<Map.Entry<Integer, String>> byMapValues = new Ordering<Map.Entry<Integer, String>>() {
   @Override
   public int compare(Map.Entry<Integer, String> left, Map.Entry<Integer, String> right) {
        return left.getValue().compareTo(right.getValue());
   }
};

Natural order

This snippet will show how to sort a hashmap based on values using guava ordering comparator class.

    
@Test
public void sort_map_by_values_guava () {
     
    // create a list of map entries
    List<Map.Entry<Integer, String>> candyBars = Lists.newArrayList(CANDY_BARS.entrySet());

    Collections.sort(candyBars, byMapValues);
    
    logger.info(candyBars);
    
    assertEquals("ALMOND JOY", candyBars.get(0).getValue());
}

Output

[
    232=ALMOND JOY, 
    222=REESE'S P-BUTTER CUPS, 
    233=REESE'S P-BUTTER CUPS, 
    284=TWIX, CARAMEL, 
    149=YORK PEPPERMINT PATTIE
]

Reverse order

Using the Ordering object created above, we will call the Ordering.reverse which will sort the map in descending order.

    
@Test
public void sort_map_by_values_guava_reverse () {
     
    // create a list of map entries
    List<Map.Entry<Integer, String>> candyBars = Lists.newArrayList(CANDY_BARS.entrySet());

    Collections.sort(candyBars, byMapValues.reverse());
    
    logger.info(candyBars);
    
    assertEquals("YORK PEPPERMINT PATTIE", candyBars.get(0).getValue());
}

Output

[
    149=YORK PEPPERMINT PATTIE, 
    284=TWIX, CARAMEL, 
    222=REESE'S P-BUTTER CUPS, 
    233=REESE'S P-BUTTER CUPS, 
    232=ALMOND JOY
]