Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting Keys with same Values -->LinkedHashMap

Tags:

java

I have written the word program in Java, and have come up with the list of words and frequencies. The result is currently stored in LinkedHashMap. The results look something like below:

garden-->2
road-->4
street-->5
park-->5
highway-->5

In the above result set, stored in LinkedHashMap, how can I sort it to only sort the keys which have the same frequency. We still want to maintain the order of frequency as given.

the result would look something like:

garden-->2
road-->4
highway-->5
park-->5
street-->5

Thank You.

like image 878
omi Avatar asked Feb 03 '18 16:02

omi


People also ask

Can LinkedHashMap be sorted?

LinkedHashMap maintains insertion order. Convert LinkedHashMap into TreeMap and after that print keys of TreeMap which are sorted in nature.

Is it possible to sort the entries in map based on the values rather than by keys?

The difference between sorting HashMap by Keys and Values is that it can have duplicate values but not duplicate Keys. We cannot use TreeMap to sort values because TreeMap sorts elements by Keys. In the following example, we have sorted the map in ascending and descending order.


1 Answers

I was able to accomplish this similarly to Boris' suggested answer. However, any IDE that I used refused to infer the generic types, so I had to explicitly specify them for the first call to Comparator#comparing as seen below:

Map<String, Integer> map = new LinkedHashMap<>();

map.put("garden", 2);
map.put("road", 4);
map.put("street", 5);
map.put("park", 5);
map.put("highway", 5);

map = map.entrySet()
         .stream()
         .sorted(Comparator.<Entry<String, Integer>, Integer>comparing(Entry::getValue)
                           .thenComparing(Comparator.comparing(Entry::getKey)))
         .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (k, v) -> {
             throw new IllegalStateException(String.format("Duplicate Key: %s", k));
         }, LinkedHashMap::new));

System.out.println(map);

The code above yields the following output:

{garden=2, road=4, highway=5, park=5, street=5}

I've noticed that you wish for the values to be in descending order, but the keys which share a value to be in ascending order. Below is that solution (which is nearly identical):

map = map.entrySet()
         .stream()
         .sorted(Comparator.<Entry<String, Integer>, Integer>comparing(Map.Entry::getValue).reversed()
                           .thenComparing(Comparator.comparing(Entry::getKey)))
         .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (k, v) -> {
                throw new IllegalStateException(String.format("Duplicate key %s", k));
         }, LinkedHashMap::new));

Note: Entry refers to java.util.Map.Entry and Collectors refers to java.util.stream.Collectors.

like image 58
Jacob G. Avatar answered Oct 07 '22 09:10

Jacob G.