Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a list of map entries

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

and I want to sort it by values according to this answer, but in reverse order. When I do

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

everything works fine. But when I try to shorten the above two lines to

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

the compiler 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>

This seems strange because the implementation of Comparator's reversed() default method simply transfers it to Collections.reverseOrder() and I can change the above line to

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

to work. But what is the correct type of Entry.comparingByValue().reversed()?

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

doesn't seem to work. Omitting the type parameter Entry<String, Integer> works, but this results in "unchecked method invocation" warning from the compiler later.

like image 602
John McClane Avatar asked Nov 15 '18 18:11

John McClane


1 Answers

The compiler is not clever enough to infer the generic type parameters in this case. You can specify them explicitly:

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

The issue is that you first need the type of the comparator returned by comparingByValue to know the type of the one returned by reversed.

I don't see any good reason why a clever compiler couldn't work backwards and know that sort requires a particular type, so reversed must be a particular type, so comparingByValue must be a particular type. But that's not how things are.

Type inference is still being worked on (as recently as Java 10), so maybe in the future, who knows.

like image 164
2 revs Avatar answered Sep 30 '22 17:09

2 revs