简体   繁体   中英

Sorting Keys with same Values -->LinkedHashMap

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.

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 .

If you are looking in JAVA7 or below, following simple code can do your work.

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

List<Entry<String, Integer>> list = new ArrayList<>();
list.addAll(map.entrySet());

Collections.sort(list, new Comparator<Entry<String, Integer>>() {

    @Override
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
        return o1.getValue()-o2.getValue() != 0 ?  o1.getValue()-o2.getValue() : o1.getKey().compareTo(o2.getKey());
    }
});
System.out.println(list);

Output:-

[garden=2, road=4, highway=5, park=5, street=5]

I guess, the code implemented by Jacob is doing the same job here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM