6

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.

1
  • data.entrySet().stream().sorted(Comparator.comparing(Entry::getValue).thenCompartring(Comparator.comparing(Entry::getKey).collect(Collectors.toMap(Entry::getKey, Entry::getValue, mergeFunction, LinkedHashMap::new)). Commented Feb 3, 2018 at 16:54

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

9 Comments

Thank You Very Much, what does Collectors refer to ?
Nice answer. I could only solve by creating two explicit comparators (c1,c2) and using sorted(c1.thenComparing(c2)). When you include the generics it starts working. Still not sure why I couldn't chain together .thenComparing() without this. You have my vote.
@AnujKumar Collectors refers to java.util.stream.Collectors
Thank You, when i run the code it says cannot find Symbol Reference for Collectors. It is strange, any clue why would it give that error.
Thanks Jacob. i think it works now, I will run some test. Appreciate your help!
|
1

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.

1 Comment

Thank You all for responding, it was a great help and the solutions given above worked! You guys are stars !!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.