Sort map by key

This example will demonstrate how to sort a map by keys. In the set up, we will create a HashMap with the key representing number of colaries burned and values being assoicated activities. For calories burned it will assume you weigh 200 pounds and performed an activity for 30 minutes. The conversion was provided by My FitnessPal exercise lookup. In a related example we demonstrate how to sort a dictionary by key in groovy.

Setup

Map<Integer, String> CALORIES_BURNED;

@Before
public void setUp () {
    
    CALORIES_BURNED = new HashMap<Integer, String>();
    CALORIES_BURNED.put(295, "Race walking");
    CALORIES_BURNED.put(249, "Punching bag");
    CALORIES_BURNED.put(499, "Rock climbing, ascending rock");
    CALORIES_BURNED.put(726, "Running (jogging), 10 mph (6 min mile)");
    CALORIES_BURNED.put(281, "Shoveling snow");
    
}

TreeMap, a sorted map

This snippet will show how to sort a map by key using a TreeMap. TreeMap elements are sorted according to the natural ordering of its keys. It also has a constructor that accepts a Comparator as shown below.

@Test
public void sort_map_by_key_java () {
    
    TreeMap<Integer, String> caloriesBurnedSorted = 
    new TreeMap<Integer, String>(CALORIES_BURNED);

    logger.info(caloriesBurnedSorted);
    
    assertThat(caloriesBurnedSorted.keySet(), contains(249, 281, 295, 499, 726));
}

Output

{
  249=Punching bag, 
  281=Shoveling snow, 
  295=Race walking, 
  499=Rock climbing, ascending rock, 
  726=Running (jogging), 10 mph (6 min mile)
}

Treemap, specific order

This snippet will show how to sort a HashMap in decending order by passing in a comparator to the TreeMap's constructor.

@Test
public void sort_map_by_key_java_reverse () {
    
    TreeMap<Integer, String> caloriesBurnedReverse = 
            new TreeMap<Integer, String>(Collections.reverseOrder());
    
    caloriesBurnedReverse.putAll(CALORIES_BURNED);

    logger.info(caloriesBurnedReverse);
    
    assertThat(caloriesBurnedReverse.keySet(), contains(726, 499, 295, 281, 249));
}

Output

{
    726=Running (jogging), 10 mph (6 min mile), 
    499=Rock climbing, ascending rock, 
    295=Race walking, 
    281=Shoveling snow, 
    249=Punching bag
}

Treemap, specific order w/ guava ordering

Following behavior shown in the snippet above, this will use the TreeMap's constructor passing in a Comparator created with Guava's fluent Ordering utility showing how to sort a HashMap in reverse order.

@Test
public void sort_map_by_key_guava () {

    TreeMap<Integer, String> caloriesBurnedReverse = 
            new TreeMap<Integer, String>(Ordering.natural().reverse());
    
    caloriesBurnedReverse.putAll(CALORIES_BURNED);

    logger.info(caloriesBurnedReverse);
    
    assertThat(caloriesBurnedReverse.keySet(), contains(726, 499, 295, 281, 249));
}

Output

{
    726=Running (jogging), 10 mph (6 min mile), 
    499=Rock climbing, ascending rock, 
    295=Race walking, 
    281=Shoveling snow, 
    249=Punching bag
}

Java 8

@Test
public void sort_map_by_key_java8() {

    Map<Integer, String> sortedMapByKey = CALORIES_BURNED
            .entrySet()
            .stream()
            .sorted(Map.Entry.comparingByKey())
//              .peek(System.out::println)
            .collect(
                    Collectors.toMap(
                            Map.Entry::getKey,
                            Map.Entry::getValue, 
                            (v1, v2) -> v1, // BinaryOperator merge function
                            LinkedHashMap::new));

    assertThat(sortedMapByKey.keySet(), contains(249, 281, 295, 499, 726));
}

Output

249=Punching bag
281=Shoveling snow
295=Race walking
499=Rock climbing, ascending rock
726=Running (jogging), 10 mph (6 min mile)