2017-02-09 177 views
8

比方说,我有一双类的Java 8比较比较并不链

public class Pair<P, Q> { 
    public P p; 
    public Q q; 


    public Pair(P p, Q q) { 
     this.p = p; 
     this.q = q; 
    } 

    public int firstValue() { 
     return ((Number)p).intValue(); 
    } 

    public int secondValue() { 
     return ((Number)q).intValue(); 
    } 
} 

我希望首先通过第一个值,对它进行排序,然后通过第二个值。现在,”如果我这样做

List<Pair<Integer, Integer>> pairList = new ArrayList<>(); 
pairList.add(new Pair<>(1, 5)); 
pairList.add(new Pair<>(2, 2)); 
pairList.add(new Pair<>(2, 22)); 
pairList.add(new Pair<>(1, 22)); 
pairList.sort(Comparator.comparing(Pair::firstValue)); 

一切工作很好,该名单是由一对第一值进行排序,但如果我这样做

pairList.sort(Comparator.comparing(Pair::firstValue).thenComparing(Pair::secondValue)); 

它失败,错误

Error:(24, 38) java: incompatible types: cannot infer type-variable(s) T,U 
(argument mismatch; invalid method reference 
    method firstValue in class DataStructures.Pair<P,Q> cannot be applied to given types 
    required: no arguments 
    found: java.lang.Object 
    reason: actual and formal argument lists differ in length) 

好吧,所以它可能无法推断参数,所以如果我这样做

pairList.sort(Comparator.<Integer, Integer>comparing(Pair::firstValue) 
              .thenComparing(Pair::secondValue)); 

它失败,错误

Error:(24, 39) java: invalid method reference 
non-static method firstValue() cannot be referenced from a static context 

为什么它比较(),而不是工作比较()。thenComparing()?

+2

尝试'比较<配对,整数> comparing'。 – shmosel

+0

@shmosel哇工作,你介意添加它作为一个答案,为什么它的工作原因!谢谢! –

+0

如果您使用[Comparator.comparingInt](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparingInt-java.util.function),我怀疑您的问题会更少.ToIntFunction-)。 – VGR

回答

5

该错误似乎与Pair的通用参数有关。一种解决方法是使用一个明确的类型,因为你已经尝试:

pairList.sort(Comparator.<Pair>comparingInt(Pair::firstValue).thenComparingInt(Pair::secondValue)); 
//      ^^^^^^ 

注从而降低您需要指定参数的数量,并避免拳击提高性能的comparingInt()

另一个解决方案是参数化类型的参考:

pairList.sort(Comparator.comparingInt(Pair<?,?>::firstValue).thenComparingInt(Pair::secondValue)); 
//          ^^^^^ 
3

它应该是:

pairList.sort(Comparator.<Pair, Integer>comparing(Pair::firstValue) 
             .thenComparing(Pair::secondValue)); 

第一类参数是指传递到比较器的类型。第二类参数是指比较器应该有效比较的类型。