【问题标题】:How to sort an object Array using a custom Comparator interface in Java 8?如何使用 Java 8 中的自定义 Comparator 接口对对象数组进行排序?
【发布时间】:2017-07-01 16:24:54
【问题描述】:

比较器的自定义实现

@FunctionalInterface
public interface Comparator<T>  {

int compare(T t1, T t2);

static <T> Comparator<T> comparing(
        Function<T, Comparable> f){
    return (p1, p2) -> f.apply(p1).compareTo(f.apply(p2));
}

default Comparator<T> thenComparing(
        Comparator<T> cmp){
            return (p1, p2) ->
                    this.compare(p1, p2) == 0 ?
                            cmp.compare(p1, p2) : this.compare(p1, p2);
}

default Comparator<T> thenComparing(
        Function<T, Comparable> f){
            Comparator<T> cmp = comparing(f);
    return thenComparing(cmp);
  }
}

我创建了一个 Person 类,其中包含三个字段,即 firstName、lastName 和 age,以及它们各自的 getter 和 setter。使用自定义 Comparator 类,我想对 main 中的一组人员进行排序,如下所示:

    Comparator<Person> cmp = Comparator
            .comparing(Person::getLastName) // Extract Property and compare
            .thenComparing(Person::getFirstName)
            .thenComparing(Person::getAge);

     Person arr[] = new Person[]{
        new Person("Sean", "Gilmore", 22),
                new Person("Aaron", "Reidy", 21),
                new Person("Jane", "Kennedy", 53),
                new Person("Mike", "English", 49)
    };


    Arrays.sort(arr, cmp);

但是Arrays.sort(arr, cmp); 抛出编译错误no instance of type variable T exists so that Comparator&lt;Person&gt; conforms to Comparator&lt;? super T&gt;

我被这个错误吓跑了,我想知道如何使用cmp Comparator 对 Person 数组进行排序。

【问题讨论】:

    标签: java sorting interface java-8 comparator


    【解决方案1】:

    classJava 中的完全限定名包括它的包名。

    Arrays.sort 方法需要 java.util.Comparator 实现。您的自定义Comparatorjava.util.Comparator 不同。

    Arrays 类中的sort 方法是static 方法,因此您不能扩展Arrays 并覆盖此方法。如果要使用Arrays.sort,请使用java.util.Comparator 的实现。没有办法解决。

    【讨论】:

    • 这意味着我必须实现排序才能使用我的自定义比较器?
    • @HarpreetSingh 或者你为你的自定义 Comparator 类编写一个外观。反正你为什么不用正版的Comparator
    • @Flown 那Facade仍然是一个java.util.Comparator
    • @CKing 这就是我的意思。
    • 为什么要重新发明轮子?
    【解决方案2】:

    您可以像这样轻松地将您的 Comparator 调整为 JDK:

    Arrays.sort(arr, cmp::compare);
    

    我相信 Guava 推荐了一种类似的模式来适应他们的功能接口,然后再针对 Java 8 进行改造。

    【讨论】:

    • @shmosei cmp:compare 仍然会给你一个java.util.Comparator。还有其他选项,但您最终无法将 java.util.Comparator 传递给相关方法,因此答案仍然存在:您不能这样做。
    • @CKing 我没有将这个问题解释为试图完全避免 JDK 的 Comparator。我认为 OP 只是在问他的自定义界面如何与内置的排序功能一起使用。
    • @shmosei 我在我的脑海中陷入了同样的论点,但后来我从问题中读到了这一行 我摆脱了这个错误,我想知道如何对 Person 进行排序使用 cmp Comparator 的数组,这使我确信 OP 显然需要解释为什么它不能完成而不是如何去做。 (OP 被抛弃了,因为他不能将Comparator 传递给采用Comparator 的方法)。这可以从 OP 对我的回答的评论中进一步推断出 所以这意味着我必须实现排序才能使用我的自定义比较器? OP 正在探索 Java一般!
    • @CKing 我听到你的声音,但我怀疑你对 OP 的话的思考比他更多:)
    • @CKing 这是我完全同意的一种说法。
    猜你喜欢
    • 2021-11-14
    • 1970-01-01
    • 2011-07-20
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    相关资源
    最近更新 更多