Java 8 Comparator比较不链

假设我有一个Pair类

public class Pair

{ 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> 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

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.comparing(Pair::firstValue) .thenComparing(Pair::secondValue)); 

它失败了,错误

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

为什么它比较()而不是比较()。然后比较()?

该错误似乎与Pair的通用参数有关。 正如您所尝试的那样,使用显式类型的一种解决方法是:

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

请注意comparingInt()减少了您需要指定的参数数量,并通过避免装箱来提高性能。

另一种解决方案是参数化类型引用:

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

它应该是:

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

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