【问题标题】:Java 8 Comparator comparing doesn't chainJava 8 Comparator 比较不链接
【发布时间】:2017-06-26 22:24:16
【问题描述】:

假设我有一个 Pair 类

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));

一切运行良好,列表按pair的第一个值排序,但如果我这样做

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

为什么它适用于 compare() 而不是 compare().thenComparing() ?

【问题讨论】:

  • 试试Comparator.&lt;Pair, Integer&gt;comparing
  • @shmosel 哇,这有效,您介意将其添加为答案,并说明其有效的原因吗!谢谢!
  • @VGR 出乎意料地没有。链式比较器的类型推断是old problem,但通常可以通过方法引用来避免。但是Pair 中的泛型参数有一些问题在这里造成了问题。
  • @MayurKulkarni 请出示您的pairList 声明。
  • @MayurKulkarni 这仍然是更好的选择,因为它避免了拳击。

标签: java java-8 comparator


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

    应该是:

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

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

    【讨论】:

      猜你喜欢
      • 2018-08-13
      • 1970-01-01
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      相关资源
      最近更新 更多