Java var and inference type ambiguity

Both calls are correct:

Collectors.groupingBy((String s)->s.toLowerCase(),Collectors.counting());
Collectors.groupingBy((String s)->s.toLowerCase(Locale.ENGLISH),Collectors.counting());

Since then, why the following one is wrong:

Collectors.groupingBy(String::toLowerCase,Collectors.counting());

after all String::toLowerCase can not correspond to the second one... Then why IntelliJ says Reference to 'toLowerCase' is ambiguous, both 'toLowerCase(Locale)' and 'toLowerCase()' match?

String::toLowerCase must be unambiguously resolved to (String s)->s.toLowerCase() or did I miss something?

Of course if I put more context to IntelliJ like:

Collector<String,?,Map<String,Long>> c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());

that is correct, but alas in Java 10 var inference type context it is wrong:

var c = Collectors.groupingBy(String::toLowerCase,Collectors.counting());

I understand that compiler can not infer the input type of counting. If I write:

Collector<String,?,Long> counter = Collectors.counting();
var c = Collectors.groupingBy(String::toLowerCase,counter);

it it correct. Thus again, why compiler is not able to infer the only acceptable form?

-------EDIT--------

I used IntelliJ/compiler interchangeably just because I used IntelliJ first and error reported was :

Reference to 'toLowerCase' is ambiguous, both 'toLowerCase(Locale)' and 'toLowerCase()' match

Compiler's error was much much more unreadable (but contains more hints on why inference fails), something like:

Demo.java:31: error: incompatible types: cannot infer type-variable(s) T#1,K,A,D,CAP#1,T#2
        Collectors.groupingBy(String::toLowerCase,Collectors.counting());
                             ^
    (argument mismatch; invalid method reference
      incompatible types: Object cannot be converted to Locale)
  where T#1,K,A,D,T#2 are type-variables:
    T#1 extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    K extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    A extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    D extends Object declared in method <T#1,K,A,D>groupingBy(Function<? super T#1,? extends K>,Collector<? super T#1,A,D>)
    T#2 extends Object declared in method <T#2>counting()
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?


Read more here: https://stackoverflow.com/questions/66278909/java-var-and-inference-type-ambiguity

Content Attribution

This content was originally published by Jean-Baptiste Yunès at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: