Generics and Comparators

I am working on generics

and found that the following code gives a compile time error in comparing method

.

Multiple markers on this line - Cannot infer type argument for comparison (Function) - Type A does not define m1 (Object), which is applicable here.

 class A<T> {
    String m1() {
        return null;
    }
}

class B {
    void test() {
        Comparator<A<String>> target = Comparator.comparing(A::m1).thenComparing(A::m1);
    }
}

      

Can someone help me understand this behavior; and how can i fix the problem?

+3


source to share


6 answers


If you specify the exact generic types in the method comparing

, the code will compile.



Comparator<A<String>> target =
    Comparator.<A<String>, String>comparing(A::m1).thenComparing(A::m1);

      

+7


source


You must provide a type parameter for class A.



Comparator<A<String>> target = Comparator.comparing(A<String>::m1).thenComparing(A<String>::m1);

      

+5


source


I checked and found that the problem is that when javac evaluates this chain:

Comparator.comparing(A::m1).thenComparing(A::m1) 

      

the outermost call in the chain:

Comparator.comparing(A::m1) 

      

has no target type. This is ok, the target type is only pushed to the innermost call of the chain. So when the method score is evaluated, the only thing javac knows is that the target is some T.

This means that javac must first output T before it tries to do the type check of the method reference - this is because the method reference 'is inaccurate

+2


source


Interest Ask. Didn't go into the JLS, but I'm guessing that type inference doesn't work in case of a chained method call. (You can see this works for a simple one Comparator<A<String>> target = Comparator.comparing(A<String>::m1);

)

One quick solution similar to the other answer is Java help which does type inference:

Comparator<A<String>> target = Comparator.comparing(A<String>::m1)
                                         .thenComparing(A::m1);

      

Note that executing this method on the first method already does the trick.

(Looking forward to see if someone can dig up the JLS to make sure such a conclusion is considered valid: P)

+2


source


you can insert

 Comparator<A<String>> target1 = Comparator.comparing(A::m1);
 Comparator<A<String>> target2 = target1.thenComparing(A::m1);


 myVarList.sort(target2);

      

+1


source


Comparator<A<String>> target = Comparator.comparing(A::m1).thenComparing(A::m1);

      

thenComparing()

expects an object Comparator

as a parameter ...

0


source







All Articles