Consider the following Java HashMap.
Map<String, String> unsortMap = new HashMap<String, String>();
unsortMap.put("Z", "z");
unsortMap.put("B", "b");
unsortMap.put("A", "a");
unsortMap.put("C", "c");
Now I wish to sort this Map by Key. One option is for me to use a TreeMap for this purpose.
Map<String, String> treeMap = new TreeMap<String, String>(unsortMap);
Another option is for me to Use Java Streams with Sorted(), as follows.
Map<String, Integer> sortedMap = new HashMap<>();
unsortMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue()));
Out of these two, which option is preferred and why (may be in terms of performance)?
Thank you
As pointed out by others dumping the sorted stream of entries into a regular HashMap
would do nothing... LinkedHashMap
is the logical choice.
However, an alternative to the approaches above is to make full use of the Stream Collectors
API.
Collectors
has a toMap
method that allows you to provide an alternative implementation for the Map
. So instead of a HashMap
you can ask for a LinkedHashMap
like so:
unsortedMap.entrySet()
.stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> v1, // you will never merge though ask keys are unique.
LinkedHashMap::new
));
Between using a TreeMap vs LinkedHashMap ... The complexity of construction is likely to be the same something like O(n log n)... Obviously the TreeMap
solution is a better approach if you plan to keep adding more elements to it... I guess you should had started with a TreeMap
in that case. The LinkedHashMap
option has the advantage that lookup is going to be O(1) on the Linked or the original unsorted map whereas as TreeMap's is something like O(log n)
so if you would need to keep the unsorted map around for efficient lookup whereas in if you build the LinkedHashMap you could toss the original unsorted map (thus saving some memory).
To make things a bit more efficient with LinkedHashMap
you should provide an good estimator of the required size at construction so that there is not need for dynamic resizing, so instead of LinkedHashMap::new
you say () -> new LinkedHashMap<>(unsortedMap.size())
.
I'm my opinion the use of a TreeMap
is more neat... as keeps the code smaller so unless there is actual performance issue that could be addressed using the unsorted and sorted linked map approach I would use the Tree
.