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 :)