While answering a question I encountered this strange behavior of Java's type inference. The following works without trouble:
new HashMap<String,Integer>().entrySet().stream()
.sorted(Map.Entry.comparingByValue());
but if we just add .reversed()
at the end, it suddenly fails:
new HashMap<String,Integer>().entrySet().stream()
.sorted(Map.Entry.comparingByValue().reversed());
Detail: in the first case, the type of comparingByValue()
is inferred as Comparator<Map.Entry<String, Integer>>
, but in the second case it changes to Comparator<Map.Entry<Object, V>>
.
The type of reversed()
is simply Comparator<T>
βan identity transformation on the type of its target. How come type inference loses it on such a seemingly trivial step? I cannot escape the hunch that this must be due to a bug in the inferring mechanics.
As a further conundrum, if we just inline the implementation of reversed()
, which is return Collections.reverseOrder(this);
:
new HashMap<String,Integer>().entrySet().stream()
.sorted(reverseOrder(Map.Entry.comparingByValue());
it works again.