0

Please note: I see that this question appears similar to this one but in that question, they are simply sorting a map. Here I need to extract keys and their values out of a map, sort them and place them, in order into another collection. And that collection must be streamable and present the elements of that stream in the order that the sorting method placed them in.


Java 11 here. I have the following POJO:

@Data // lombok generates ctor, getters, setters, etc.
public class Answer {
    private String text;
    // ... many other fields here, omitted for brevity
}

I have a Map<Answer,Integer> that represents the number of instances for each Answer, for example:

Map<Answer,Integer> answerCounts = new HashMap<>();
answerCounts.put(answer1, 14); // answer #1 occurs 14 times
answerCounts.put(answer2, 7);
answerCounts.put(answer3, 239);
answerCounts.put(answer4, 7);
answerCounts.put(answer5, 54);
answerCounts.put(answer6, 2);

I would like to convert this map into a collection (likely either a List or Set) where the Answer elements are ordered according to their count values in the map. In the case of "ties" (where two map keys have the same count value) then it doesn't really matter what order the Answer elements appear in, so long as they are sorted correctly according to other, non-tying elements.

So using the map example above, I'd like the output of this conversion to be a list/set that provides Answer elements in the following order:

  1. Answer #3 (count = 239)
  2. Answer #5 (count = 54)
  3. Answer #1 (count = 14)
  4. Answer #2 (count = 7)
  5. Answer #4 (count = 7) (<-- #2 and #4 have same count so their respective order doesn't matter to me)
  6. Answer #6 (count = 2)

Any idea how I could accomplish this? The objective is to have a collection that I can then stream over (someCollection.stream()...) and process elements in order of how they appear in the "counts map".

hotmeatballsoup
  • 385
  • 6
  • 58
  • 136
  • 1
    Does this answer your question? [Sort a Map by values](https://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values) – pringi Feb 07 '22 at 12:09
  • Create an additional class `CountedAnswer`? Or you can just iterate the `Map.Entry`s. – daniu Feb 07 '22 at 12:09
  • Many different ways. You can use a TreeMap (which does sorting by itself) and provide a Comparator that sorts on your preferred criteria. Then you only need one colluction ... that tree map instance. – GhostCat Feb 07 '22 at 12:10
  • @pringi no in that question they are doing the sorting but are not processing the resultant map in the stream-based fashion like I need. I need sorting and stream traversal. – hotmeatballsoup Feb 07 '22 at 12:20
  • The question proposed by @pringi _is_ exactly what you need. Several answers, including the top one, build a `LinkedHashMap` in the order you need. Just call `.entrySet().stream()` on it. Those answers rely on an intermediate `List` or `Stream` that you could use as well. – Didier L Feb 07 '22 at 12:45
  • No it duzzint that question answers another question – hotmeatballsoup Feb 07 '22 at 13:15

1 Answers1

2

Use a LinkedHashMap instead of a Map. The difference is that the first one has an order, so when you sort it it will remain sorted (until you modify or add new elements)

By the way, you can stream over a Map

answerCounts.entrySet()
  .stream()
  .sorted(Map.Entry.comparingByValue())
  .forEach(System.out::println);

This will sort the Map but in the wrong order, and i can't find a way to reverse it

AlexM28
  • 71
  • 2