7

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.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • 3
    May this help: http://stackoverflow.com/questions/27205309/misunderstanding-about-comparator-in-java-8 and http://stackoverflow.com/questions/25172595/comparator-reversed-not-compiles-using-lambda It also surprises me (as I asked the question), but it seems that it's a weakness in the type inference mechanism. So deal with it for the moment :-) – user2336315 Jan 25 '15 at 15:27
  • 1
    @user2336315 with input from Jon Skeet and Brian Goetz (!). Good finds. – Boris the Spider Jan 25 '15 at 15:33
  • 2
    I'm closing my own question as a duplicate of the one with user Holger's answer because I find that answer the most relevant and complete. Even the answer from Stuart Marks (also a member of the core Java team) states that he is not entirely sure why this happens :) What is clear is that inference fails in the method receiver position, a fact perfectly aligned with my finding. – Marko Topolnik Jan 25 '15 at 16:02

0 Answers0