2017-02-02 43 views
3

我有以下类:如何获得Comparator.comparing正确推断类型参数?

import java.util.ArrayList; 
import java.util.Comparator; 
import java.util.List; 

import org.apache.commons.lang3.tuple.Pair; 

public class Sorter { 
    private List<Pair<Long, NameDTO>> dtoPairs = new ArrayList<>(); 

    public Sorter() { 
     Comparator<Pair<Long, NameDTO>> bySize = Comparator.comparing(Pair::getLeft); 
     Comparator<Pair<Long, NameDTO>> byName = Comparator.comparing(p -> p.getRight().getName()); 
     dtoPairs.sort(bySize.reversed().thenComparing(byName)); 
    } 
} 

class NameDTO { 
    private String name; 
    public String getName() { 
     return name; 
    } 
} 

这将编译没有问题。但是,如果我尝试内联变量是这样的:

dtoPairs.sort(Comparator.comparing(Pair::getLeft).reversed().thenComparing(Comparator.comparing(p -> p.getRight().getName()))); 

我得到以下编译错误:

Sorter.java:[18,51] incompatible types: cannot infer type-variable(s) T,U 
    (argument mismatch; invalid method reference 
     method getLeft in class org.apache.commons.lang3.tuple.Pair<L,R> cannot be applied to given types 
     required: no arguments 
     found: java.lang.Object 
     reason: actual and formal argument lists differ in length) 

我怎么能写这样的表达使Java正确理解的参数?

+0

的[对比和thenComparing给出编译错误]可能的复制(http://stackoverflow.com/questions/40500280/comparing-and-thencomparing-gives-compile-error) –

+1

@ OleV.V:我不知道认为这是重复的,它没有泛泛的方法参考,这是什么扔我在这里。 – Keppil

回答

3

您需要告诉编译器通用参数的类型。 试试这个:

dtoPairs.sort(
    Comparator.comparing(Pair<Long, NameDTO>::getLeft) 
    .reversed() 
    .thenComparing(Comparator.comparing(p -> p.getRight().getName()))); 
+0

啊,很酷,我没有看到这种方法的参考语法。 '(Pair )p'显然不需要,我所需要的就是'Pair :: getLeft'调整。 – Keppil

+0

没错。我只是添加了它,以便更清楚。我从我的答案中删除了它。 –

2

本声明编译就好:

dtoPairs.sort(Comparator.comparing((Pair<Long, NameDTO> p) -> p.getLeft()) 
         .reversed() 
         .thenComparing(Comparator.comparing(p -> p.getRight().getName()))); 

...这指出了为什么你不能编译的原因:当你这样做的方法引用(Pair:getLeft),Pair是原始的,它的类型参数被忽略。这使thenComparing(...)方法预计Comparator<Pair, Object>