Collections.sort(list) 和 Collections.sort(list,comparator) 的区别

问题描述 投票:0回答:3

有什么区别:

    public FlyingRabbit(){
        list = new ArrayList<Sellable>();
    }
    public void sort(Comparator<Sellable> comp) {
        Collections.sort(list, comp);
    }

和:

public class CompareCategory implements Comparator<Sellable> {
    @Override
    public int compare(Sellable s1, Sellable s2) {
            return (s1.getCategory()).compareTo(s2.getCategory());
    }
}

我很困惑为什么我需要使用比较器

comp
而不是在
compare
内使用
CompareCategory

java list sorting comparator comparable
3个回答
3
投票

Collections.sort(List<T>)
根据其元素的
自然顺序
对给定的 List 进行排序。类可以通过实现
Comparable
接口来定义其自然顺序。该接口提供了一个方法,
compareTo()
,它返回:

负整数、零或正整数,因为该对象小于、等于或大于指定对象。

另一方面,

Collections.sort(List<T>, Comparator<T>)
根据给定的
List
Comparator
的元素进行排序。元素的自然顺序被忽略。当
List
的元素已经表现出自然排序,但我们需要按不同的顺序对它们进行排序时,第二种方法会派上用场。

这是一个简短的示例,其中包含

Person
列表。该列表首先按
Person
的自然顺序(
lastName
name
)排序,然后按给定的
Comparator
进行比较,仅通过
age
进行比较。

class Person implements Comparable<Person> {

    private String name;
    private String lastName;
    private int age;

    // Defining Person's natural ordering by creating a comparator that compares by last name and name
    private static final Comparator<Person> naturalOrdering = Comparator.comparing(Person::getLastName).thenComparing(Person::getName);

    public Person(String name, String lastName, int age) {
        this.name = name;
        this.lastName = lastName;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Person o) {
        return naturalOrdering.compare(this, o);
    }

    @Override
    public String toString() {
        return String.format("%s %s %d", name, lastName, age);
    }

    public static void main(String[] args) {
        List<Person> list = new ArrayList<>(List.of(
                new Person("Luke", "O'Brien", 30),
                new Person("Conan", "O'Brien", 25),
                new Person("John", "Doe", 50)
        ));

        // Original unordered list
        System.out.println(list);

        // List ordered by Person's natural ordering (last name and name)
        Collections.sort(list);
        System.out.println(list);

        // List ordered by custom comparator (age)
        Collections.sort(list, Comparator.comparing(Person::getAge));
        System.out.println(list);
    }
}

1
投票

如果 Sellable 实现了 Comparable 接口,你可以使用 Collections.sort(list)。 否则,您应该创建自己的比较器并使用 Collections.sort(list, comparator)。因为必须有一个规则来比较 Sellable 类型的元素。


0
投票

当列表中包含的对象实现 Comparable 接口时,您不需要提供

比较器

比较器与比较器

这就是 文档定义此接口的用途:

该接口对每个类的对象强加了总排序 实现它。这种排序被称为 class 的 自然排序,类的

compareTo
方法被称为 其自然的比较方法。

另一方面, comparator - 是一个对象,用于为没有 natural ordering 的对象集合提供排序,即没有明显的特定方式可以对这些对象进行排序,并且他们的班级没有实现

Comparable

当需要根据情况对对象进行不同的排序时,比较器会很方便。例如,您有一个班级

Student
,学生可以按姓名、ID、成绩等进行排序。您可以通过创建一个实现接口
Comparator
的类并覆盖来为每种情况创建一个比较器方法
compare()
(如您列出的代码中所示)或使用静态方法,如 Java 引入的
Comparator.comparing()
8.

话虽如此,接口

Comparator
Comparable
具有相同的目的(以方便对象的比较),但具有不同的用例。

警告:不要通过在compareTo()方法中创建比较器

内部
将事物混合在一起,如另一个答案中所示。这是一个糟糕的主意。为什么?因为这样的实现将为每次调用此方法创建一个“新的比较器”。要对 10.000.000 元素列表进行排序,需要进行
10.000.000 * log(10.000.000)
比较,每次比较
compareTo()
将被调用,并创建
comparator
的新实例。它会对应用程序性能产生负面影响,因为创建对象的成本很高,它需要内存分配,然后给垃圾收集器带来大量工作。 流畅排序

为了对列表进行排序,您可以使用

sort()

实用程序类中的静态方法

Collections
,这些方法从早期版本开始就是 JDK 的一部分。您可以在互联网上找到很多代码片段,其中使用了
Collection.sort()
使用 Java 8 方法 

List#sort()

已在 List 接口中引入,您不再需要求助于

Collections
类中的静态方法。相反,您可以直接调用列表上的方法
sort()
,请注意,它始终需要比较器作为参数。如果列表中的元素实现了
Comparable
,您应该传递
null
来代替:

如果指定的比较器是
null

,则此列表中的所有元素 必须实现

Comparable
接口和元素的
natural
应使用订购

myList.sort(null); // only if element of the implement Comparable
	
© www.soinside.com 2019 - 2024. All rights reserved.