4

Given following code:

@Test
public void test7() {
    Map<String, Integer> sortedData = new HashMap<>();
    sortedData.put("One", 1);
    sortedData.put("Two", 2);
    sortedData.put("Three", 3);

    Stream<Map.Entry<String, Integer>> stream = sortedData.entrySet().stream();
    List<String> sorted = stream
            .sorted(Comparator.comparing(Map.Entry::getValue))
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
} 

It succeeds to compile, but when I change

.sorted(Comparator.comparing(Map.Entry::getValue))

to

.sorted(Comparator.comparing(Map.Entry::getValue).reversed())

the compiler complains that Non static method can't be referenced in static context

I could imagine that it is because getValue is not a static method of Map.Entry, but I can't explain the problem here.

Eran
  • 387,369
  • 54
  • 702
  • 768
Tom
  • 5,848
  • 12
  • 44
  • 104

1 Answers1

12

It's interesting,

.sorted(Comparator.comparing(Map.Entry<String,Integer>::getValue).reversed ())

works.

Perhaps using raw Map.Entry confuses the compiler.

BTW, this also works:

.sorted(Collections.reverseOrder(Comparator.comparing(Map.Entry::getValue)))

(Collections.reverseOrder(this) is what reversed() returns)

Eran
  • 387,369
  • 54
  • 702
  • 768
  • Thanks @eran. The IDEA IDE indicates that `` in `Map.Entry::getValue)` is redundant, :-) – Tom Oct 24 '17 at 07:38
  • @Tom that's funny – Eran Oct 24 '17 at 07:39
  • 1
    Target type inference doesn’t work through method invocation chains, therefore the types for the first invocation have to be inferred using the argument, thus, either `Map.Entry::getValue` or `(Map.Entry e) -> e.getValue()` is needed. Or you change the code from an invocation chain to nested invocation: `Collections.reverseOrder(Comparator.comparing(Map.Entry::getValue))` or just `Map.Entry.comparingByValue(Comparator.reverseOrder())`… – Holger Oct 24 '17 at 13:39