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 ?
Collectors.counting()
asObject
, hence it expects thatString
has a methodtoLowerCase(Object)
. – Nepali(Function<String, String>) String::toLowerCase
. – Anorthic