Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Sorting a Map using Steams VS TreeMap

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

like image 479
Keet Sugathadasa Avatar asked Oct 15 '25 18:10

Keet Sugathadasa


1 Answers

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.

like image 90
Valentin Ruano Avatar answered Oct 17 '25 08:10

Valentin Ruano



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!