Convert HashMap to TreeMap in Java
This post will discuss how to convert HashMap to TreeMap in Java. The resultant TreeMap should contain all mappings of the HashMap, sorted by their natural ordering of keys.
We know that HashMap is implemented using a Hash Table, whereas a Red-Black tree implements TreeMap.
HashMap is much faster than TreeMap (O(1) time versus O(log(n)) time for inserting and searching but offers no ordering guarantees like TreeMap. In a TreeMap, the map is ordered according to the natural ordering of its keys or a specified Comparator in the TreeMap’s constructor.
If we want near-HashMap performance and insertion-order iteration, we can use LinkedHashMap. Following are a few ways to convert HashMap to TreeMap in Java:
1. Using Java 8
The idea is to convert HashMap to a stream and collect elements of a stream in a TreeMap using the Stream.collect() method, which accepts a collector.
We can use collector returned by Collectors.toMap() method that accepts TreeMap constructor reference TreeMap::new.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.stream.Collectors; class Main { // Generic method to construct a new `TreeMap` from `HashMap` public static <K, V> Map<K, V> getTreeMap(Map<K, V> hashMap) { Map<K, V> treeMap = hashMap.entrySet() .stream() .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> newValue, TreeMap::new)); return treeMap; } public static void main(String[] args) { Map<String, String> hashMap = new HashMap<>(); hashMap.put("RED", "#FF0000"); hashMap.put("BLUE", "#0000FF"); hashMap.put("GREEN", "#008000"); // construct a new `TreeMap` from `HashMap` Map<String, String> treeMap = getTreeMap(hashMap); System.out.println(treeMap); } } |
Output:
{BLUE=#0000FF, GREEN=#008000, RED=#FF0000}
Here’s an equivalent version without using the Stream API.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import java.util.HashMap; import java.util.Map; import java.util.TreeMap; class Main { // Generic method to construct a new `TreeMap` from `HashMap` public static <K, V> Map<K, V> getTreeMap(Map<K, V> hashMap) { Map<K, V> treeMap = new TreeMap<>(); for (Map.Entry<K, V> kvEntry : hashMap.entrySet()) { treeMap.put(kvEntry.getKey(), kvEntry.getValue()); } return treeMap; } public static void main(String[] args) { Map<String, String> hashMap = new HashMap<>(); hashMap.put("RED", "#FF0000"); hashMap.put("BLUE", "#0000FF"); hashMap.put("GREEN", "#008000"); // construct a new `TreeMap` from `HashMap` Map<String, String> treeMap = getTreeMap(hashMap); System.out.println(treeMap); } } |
Output:
{BLUE=#0000FF, GREEN=#008000, RED=#FF0000}
2. Plain Java
To construct a new TreeMap from HashMap, we can either pass HashMap instance to the TreeMap constructor or to putAll() method.
|
1 2 3 4 5 6 7 8 |
// Generic method to construct a new `TreeMap` from `HashMap` public static <K, V> Map<K, V> getTreeMap(Map<K, V> hashMap) { Map<K, V> treeMap = new TreeMap<>(); treeMap.putAll(hashMap); return treeMap; } |
3. Using Guava Library
Guava also provides TreeMap implementation, which can create an empty TreeMap instance.
|
1 2 3 4 5 6 7 8 |
// Generic method to construct a new `TreeMap` from `HashMap` public static <K extends Comparable, V> Map<K, V> getTreeMap(Map<K, V> hashMap) { Map<K, V> treeMap = Maps.newTreeMap(); treeMap.putAll(hashMap); return treeMap; } |
4. Conversion between incompatible types
If HashMap and TreeMap is expected to have incompatible types of keys or values, we’ll need to convert them manually:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import java.util.HashMap; import java.util.Map; import java.util.TreeMap; class Main { public static void main(String[] args) { Map<String, String> hashMap = new HashMap<>(); hashMap.put("1", "ONE"); hashMap.put("2", "TWO"); hashMap.put("3", "THREE"); // construct a new `TreeMap<Integer, String>` from `HashMap<String, String>` Map<Integer, String> treeMap = new TreeMap<>(); for (Map.Entry<String, String> e: hashMap.entrySet()) { treeMap.put(Integer.parseInt(e.getKey()), e.getValue()); } System.out.println(treeMap); } } |
Output:
{1=ONE, 2=TWO, 3=THREE}
We can do better in Java 8 and above, as demonstrated below:
|
1 2 3 4 5 6 |
// construct a new `TreeMap<Integer, String>` from `HashMap<String, String>` Map<Integer, String> treeMap = hashMap.entrySet().stream() .collect(Collectors.toMap(x -> Integer.parseInt(x.getKey()), x -> x.getValue(), (oldValue, newValue) -> newValue, TreeMap::new)); |
Or even better,
|
1 2 3 4 5 6 7 |
// construct a new `TreeMap<Integer, String>` from `HashMap<String, String>` Map<Integer, String> treeMap = new TreeMap<>(); hashMap.entrySet() .stream() .forEach(x -> treeMap.put(Integer.parseInt(x.getKey()), x.getValue())); |
That’s all about converting HashMap to TreeMap in Java.
Exercise: Convert HashMap to LinkedHashMap in Java
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)