Map.Entry.comparingByValue().reversed() 的类型是什么?

What is the type of Map.Entry.comparingByValue().reversed()?

我有一个地图条目列表

Map<String, Integer> map = new HashMap<>();
...(fill the map)...
List<Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());

我想根据 this answer 按值对它进行排序,但顺序相反。当我这样做时

Comparator<Entry<String, Integer>> cmp = Entry.comparingByValue();
entries.sort(cmp.reversed());

一切正常。但是当我尝试将以上两行缩短为

entries.sort(Entry.comparingByValue().reversed());

编译器returns

error: incompatible types: Comparator<Entry<Object,V>> cannot be converted to Comparator<? super Entry<String,Integer>>
        entries.sort(Entry.comparingByValue().reversed());
  where V is a type-variable:
    V extends Comparable<? super V>

这看起来很奇怪,因为 Comparator 的 reversed() 默认方法的实现只是将它转移到 Collections.reverseOrder() 我可以将上面的行更改为

entries.sort(Collections.reverseOrder(Entry.comparingByValue()));

上班。但是 Entry.comparingByValue().reversed() 的正确类型是什么?

Comparator<Entry<String, Integer>> cmp = Entry.comparingByValue().reversed();

好像不行。省略类型参数 Entry<String, Integer> 是可行的,但这会导致编译器稍后发出 "unchecked method invocation" 警告。

当你缩短时

Comparator<Entry<String, Integer>> cmp = Entry.comparingByValue();
entries.sort(cmp.reversed());

entries.sort(Entry.comparingByValue().reversed());

你删除了从 cmp 的声明中收集到的类型信息。编译器仍然需要知道该信息,因此您需要将泛型类型添加到 Entry:

entries.sort(Entry.<String, Integer>comparingByValue().reversed());

在这种情况下,编译器不够聪明,无法推断泛型类型参数。您可以明确指定它们:

entries.sort(Entry.<String, Integer>comparingByValue().reversed());

问题是您首先需要 comparingByValue 返回的比较器的类型才能知道 reversed 返回的比较器的类型。

我看不出为什么聪明的编译器不能逆向工作并且知道 sort 需要特定类型,所以 reversed 必须是特定类型,所以 comparingByValue 必须是特定类型。但事实并非如此。

类型推断仍在进行中 (as recently as Java 10),所以也许在将来,谁知道呢。