2

I have the following code to collect a map from the stream, and convert it to a treemap

Map<String, String> result = myMap.values().stream().collect(Collectors.toMap(Person::getScore, Person::getName));
    return new TreeMap<>(result);

Is there a way I could return a descending sorted treeMap in the same line? I cannot pass the comparator as an argument.

Stefan Zobel
  • 3,182
  • 7
  • 28
  • 38
Jeeppp
  • 1,553
  • 3
  • 17
  • 39

2 Answers2

4

I think you could use the four argument toMap method that returns a collector. Assuming the getScore method returns an Integer(or you can stay with String if you want but it will be less usable I think) :

//supplier of TreeMap with your custom comparator
Supplier<TreeMap<Integer, String>> myMapSupplier = () -> new TreeMap<>(Comparator.reverseOrder());

Map<Integer, String> result = myMap.values()
             .stream()
             .collect(Collectors.toMap(Person::getScore, Person::getName, (s, s2) -> s, myMapSupplier));

The last element is the supplier of the Map. As documentation states :

mapSupplier - a function which returns a new, empty Map into which the results will be inserted

So you can still have a TreeMap with a custom Comparator in a single call.

Michał Krzywański
  • 15,659
  • 4
  • 36
  • 63
2

You can use sorted with Comparator and use LinkedHashMap to collect as below,

Map<String, String> result = myMap.values().stream()
                .sorted(Comparator.comparing(Person::getScore, Comparator.reverseOrder()))
                .collect(Collectors.toMap(Person::getScore, Person::getName, (x, y) -> x,LinkedHashMap::new));

I would suggest using int for score as String would be lexically compared. So your result map would be Map<Integer, String>.

I hope it helps.

Vikas
  • 6,868
  • 4
  • 27
  • 41