Code refuses to compile when using comparator with lambda

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Mar 20 03:44:42 PDT 2013


So, let's rewrite your example to something self-contained which should 
have same features as yours:

import java.util.*;

class Test {
     void test(List<String> ls) {
         ls.sort(Comparators.comparing(String::length));
     }
}

 From a type-inference point of view, this has all it needs in order to 
compile - in fact the compiler is able to type-check the method 
reference, knowing that the argument of the comparator would be a String.

The problem happens with overload resolution:

TestCrash.java:5: error: reference to comparing is ambiguous
         ls.sort(Comparators.comparing(String::length));
                            ^
   both method <T#1>comparing(ToLongFunction<? super T#1>) in 
Comparators and method <T#2>comparing(ToDoubleFunction<? super T#2>) in 
Comparators match
   where T#1,T#2 are type-variables:
     T#1 extends Object declared in method 
<T#1>comparing(ToLongFunction<? super T#1>)
     T#2 extends Object declared in method 
<T#2>comparing(ToDoubleFunction<? super T#2>)
1 error


This problem is caused by a glitch in the current EDR - the most precise 
most specific check (which would allow to disambiguate between these two 
methods), is currently only applied when the argument types of the two 
applicable function descriptors are the same; it's not the case here, as 
one descriptor accepts T#1, while the other accepts T#2.

The spec (and compiler) need to be updated in order to make this work. 
Good news is that we knew about this and we are working to address the 
problem.

Maurizio


On 19/03/13 18:23, Mrityunjay Sharma wrote:
> Hi All,
> The below code refuses to compile when using comparator.
>
> *shapes1.sort(Comparators.comparing(Shape::getSize));*
> *
> *
> but when i provide the type implementation (as below) of above lambda
> expression, it works properly.
>
>                 *shapes1.sort(Comparators.comparing(*
> * new ToIntFunction<Shape>() {*
> * public int applyAsInt(Shape s) {*
> * return s.getSize();*
> * }}*
> * ));*
>
> Please let me know if i am missing something.
>
> Regards,
> MJ
>



More information about the lambda-dev mailing list