Explain Codes LogoExplain Codes Logo

How can I sort Map values by key in Java?

java
map-implementation
tree-map
custom-comparator
Anton ShumikhinbyAnton Shumikhin·Sep 20, 2024
TLDR
Map<String, Integer> sortedMap = new TreeMap<>(map); sortedMap.forEach((key, value) -> System.out.println(key + ": " + value));

Here, we're using a TreeMap to sort a Map by its keys in natural order. This one-liner clones your original map into a brand new, tidy, sorted one.

Deep dive: Under the hood of TreeMap

TreeMap is a nifty Map implementation, based on a red-black tree. It should be your go-to when you need to sort by keys because:

  • It sorts its keys in natural order, or by a custom comparator when you need out-of-the box behavior
  • All key-targeted operations (get, put) are logarithmic (O(log N)) in complexity
  • Its keySet and values methods return collections that maintain the key order

Be careful not to trip over a TreeMap where you could easily step over a HashMap. TreeMap does neatly sort your keys, but this also makes it slower to use:

  • 1.3x slower on average with 10,000 items
  • 1.6x slower on average with 100,000 items

Shaping custom keys and comparators

What if our keys aren't simple strings or integers but instances of a custom class? Fear not, a custom comparator comes to the rescue:

TreeMap<CustomKey, String> sortedMap = new TreeMap<>(new Comparator<CustomKey>() { @Override public int compare(CustomKey k1, CustomKey k2) { // Your comparison logic... but don't compare apples and oranges here! } }); sortedMap.putAll(unsortedMap);

When isn't a map a map? When it's a set!

If you just need the sorted keys and don't care about the values, use a TreeSet:

SortedSet<CustomKey> sortedKeys = new TreeSet<>(map.keySet());

Not-so-conventional sorting tricks

Morphing from HashMap to TreeMap

Turn your HashMap into a TreeMap by performing a magic trick:

Map<CustomKey, String> hashMap = new HashMap<>(); // ...populate hashMap... Map<CustomKey, String> sortedMap = new TreeMap<>(hashMap);

The one-off sorting affair

If you only need to sort keys once in a blue moon, you might not need a TreeMap at all. Use an ArrayList:

List<CustomKey> sortedKeys = new ArrayList<>(map.keySet()); Collections.sort(sortedKeys);

Chat bot style Q & A construction

Want to organize your question-answer pairs in natural order? Go with TreeMap!

TreeMap<String, String> qaMap = new TreeMap<>(); //...populate qaMap with question-answer pairs... qaMap.forEach((question, answer) -> System.out.println("Q: " + question + "\n" + "A: " + answer));

Custom sorting logic - because you're unique!

To implement your out-of-box logic when the natural order isn't just cutting it, define a custom comparator:

TreeMap<CustomKey, String> sortedMap = new TreeMap<>(new CustomComparator());

TreeMap vs. Large Maps: The Clash

For large maps, time is of the essence. There it's important to weigh between sort time and iteration time. Utilize tools like profiling to make informed decisions on when to opt for TreeMap over other maps like LinkedHashMap.