'TreeMap with comparator comparing length of string in keys

I need a TreeMap mapping Strings to Integers using the length of the string as the sorting criteria. This is my code:

TreeMap<String, Integer> map = new TreeMap<>(Comparator.comparingInt(String::length)) {{
  put("one", 1);
  put("two", 2);
  put("three", 3);
  put("four", 4);
  put("five", 5);
  put("six", 6);
}};

I expect the content of the map to be something like this:

{one=1, two=2, six=6, four=4, five=5, three=3}

but what I get instead is:

{one=6, four=5, three=3}

Looking at the code of the put method of the TreeMap, I can see that if a Comparator has been defined, then it uses the value returned by the comparator to decide if to create a new key in the map, or to overwrite the value of an existing one. In my case, since I have three keys of length 3 ("one", "two" and "six"), it inserts only one key of length 3 (the first inserted, "one") and updates its value (first 1, then 2 and at last 6). The same goes for key of length 4 ("four" and "five").

How can I have the tree map inserting all the keys I defined ("one", "two", "three", "four", "five", "six") sorted by the length of the key?



Solution 1:[1]

You need a double comparator, where you first compare the string lengths, then the strings themselves. Like:

public class MyTreeMapComparator implements Comparator<String> {
  public int compare(String one, String two) {
    if (one.length() == two.length()) {
      return one.compareTo(two);
    } else return two.length() - one.length();
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 samabcde