Collections.sort(list) 和 Collections.sort(list,comparator) 的区别
Difference between Collections.sort(list) and Collections.sort(list,comparator)
有什么区别:
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
而不是在 CompareCategory
.
中使用 compare
如果 Sellable 实现了 Comparable 接口,您可以使用 Collections.sort(list)。
否则你应该创建自己的 Comparator 并使用 Collections.sort(list, comparator)。因为必须有一个规则来比较 Sellable 类型的元素。
Collections.sort(List<T>)
按其元素的 natural ordering 对给定的 List
进行排序。对象的自然排序可以通过在相应的 class 中实现 Comparable
接口来定义。这个接口提供了一个方法,compareTo
,returns
a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
另一方面,Collections.sort(List<T>, Comparator<T>)
根据给定的 Comparator
对 List
的元素进行排序。排序时将忽略它们的自然顺序。当 List
的元素已经拥有它们的自然顺序但我们想按不同的标准对它们进行排序时,第二种方法就派上用场了。
这是一个简单的示例,其中 Person
class 显示姓名、姓氏和年龄。
class Person implements Comparable<Person> {
private String name, lastName;
private int age;
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) {
//Defining Person's natural ordering by creating a comparator and comparing by last name and then name the current object and the given paramter
return Comparator.comparing(Person::getLastName).thenComparing(Person::getName).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("Matt", "O'Brien", 30),
new Person("Conan", "O'Brien", 25),
new Person("Frank", "Johnson", 50)
));
//Original unordered list
System.out.println(list);
//List ordered by Person's natural ordering (last name and then name)
Collections.sort(list);
System.out.println(list);
//List ordered by custom criteria (age)
Collections.sort(list, Comparator.comparing(Person::getAge));
System.out.println(list);
}
}
当列表中包含的对象实现Comparable
接口时,您不需要提供比较器。
比较器与比较器
这就是documention定义这个接口的目的:
This interface imposes a total ordering on the objects of each class
that implements it. This ordering is referred to as the class's
natural ordering, and the class's compareTo
method is referred to as
its natural comparison method.
另一方面,比较器 - 是一个对象,用于为没有自然排序的对象集合提供排序,即没有明显的特定方式可以对这些对象进行排序,并且它们的 class 没有实现 Comparable
.
当需要根据情况以不同方式对对象进行排序时,比较器很方便。例如,您有一个 class Student
,学生可以按姓名、ID、成绩等进行排序。您可以通过创建 class 实现接口 Comparator
并覆盖方法 compare()
(就像在您列出的代码中一样)或通过使用像 Java 8 引入的 Comparator.comparing()
这样的静态方法.
话虽如此,接口 Comparator
和 Comparable
的用途相同(便于比较对象),但用例不同。
警告: 不要通过创建 比较器 inside compareTo()
方法,如另一个答案所示。这是个糟糕的主意。为什么?因为这样的实现将为该方法的每次调用创建一个 new comparator。要对 10.000.000
元素的列表进行排序,需要进行 10.000.000 * log(10.000.000)
次比较,每次比较都会调用 compareTo()
并且 comparator 的新实例将被调用被创建。它会对应用程序性能产生负面影响,因为创建对象的成本很高,它需要内存分配,然后给垃圾收集器带来大量工作。
流畅排序
为了对列表进行排序,您可以使用 Collections
实用程序 class 中的静态方法 sort()
,它们自很早以来就是 JDK 的一部分版本。您可以在 Internet 上找到很多 code-snippets,其中使用了 Collection.sort()
。
使用 Java 8 方法 List#sort() 已在 List
接口中引入,您不再需要求助于 Collections
class 中的静态方法.相反,您可以直接调用列表中的方法 sort()
,请注意它始终需要一个比较器作为参数。如果列表的元素实现 Comparable
你应该传递 null
而不是:
If the specified comparator is null
then all elements in this list
must implement the Comparable
interface and the elements' natural
ordering should be used.
myList.sort(null); // only if element of the implement Comparable
有什么区别:
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
而不是在 CompareCategory
.
compare
如果 Sellable 实现了 Comparable 接口,您可以使用 Collections.sort(list)。 否则你应该创建自己的 Comparator 并使用 Collections.sort(list, comparator)。因为必须有一个规则来比较 Sellable 类型的元素。
Collections.sort(List<T>)
按其元素的 natural ordering 对给定的 List
进行排序。对象的自然排序可以通过在相应的 class 中实现 Comparable
接口来定义。这个接口提供了一个方法,compareTo
,returns
a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
另一方面,Collections.sort(List<T>, Comparator<T>)
根据给定的 Comparator
对 List
的元素进行排序。排序时将忽略它们的自然顺序。当 List
的元素已经拥有它们的自然顺序但我们想按不同的标准对它们进行排序时,第二种方法就派上用场了。
这是一个简单的示例,其中 Person
class 显示姓名、姓氏和年龄。
class Person implements Comparable<Person> {
private String name, lastName;
private int age;
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) {
//Defining Person's natural ordering by creating a comparator and comparing by last name and then name the current object and the given paramter
return Comparator.comparing(Person::getLastName).thenComparing(Person::getName).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("Matt", "O'Brien", 30),
new Person("Conan", "O'Brien", 25),
new Person("Frank", "Johnson", 50)
));
//Original unordered list
System.out.println(list);
//List ordered by Person's natural ordering (last name and then name)
Collections.sort(list);
System.out.println(list);
//List ordered by custom criteria (age)
Collections.sort(list, Comparator.comparing(Person::getAge));
System.out.println(list);
}
}
当列表中包含的对象实现Comparable
接口时,您不需要提供比较器。
比较器与比较器
这就是documention定义这个接口的目的:
This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's
compareTo
method is referred to as its natural comparison method.
另一方面,比较器 - 是一个对象,用于为没有自然排序的对象集合提供排序,即没有明显的特定方式可以对这些对象进行排序,并且它们的 class 没有实现 Comparable
.
当需要根据情况以不同方式对对象进行排序时,比较器很方便。例如,您有一个 class Student
,学生可以按姓名、ID、成绩等进行排序。您可以通过创建 class 实现接口 Comparator
并覆盖方法 compare()
(就像在您列出的代码中一样)或通过使用像 Java 8 引入的 Comparator.comparing()
这样的静态方法.
话虽如此,接口 Comparator
和 Comparable
的用途相同(便于比较对象),但用例不同。
警告: 不要通过创建 比较器 inside compareTo()
方法,如另一个答案所示。这是个糟糕的主意。为什么?因为这样的实现将为该方法的每次调用创建一个 new comparator。要对 10.000.000
元素的列表进行排序,需要进行 10.000.000 * log(10.000.000)
次比较,每次比较都会调用 compareTo()
并且 comparator 的新实例将被调用被创建。它会对应用程序性能产生负面影响,因为创建对象的成本很高,它需要内存分配,然后给垃圾收集器带来大量工作。
流畅排序
为了对列表进行排序,您可以使用 Collections
实用程序 class 中的静态方法 sort()
,它们自很早以来就是 JDK 的一部分版本。您可以在 Internet 上找到很多 code-snippets,其中使用了 Collection.sort()
。
使用 Java 8 方法 List#sort() 已在 List
接口中引入,您不再需要求助于 Collections
class 中的静态方法.相反,您可以直接调用列表中的方法 sort()
,请注意它始终需要一个比较器作为参数。如果列表的元素实现 Comparable
你应该传递 null
而不是:
If the specified comparator is
null
then all elements in this list must implement theComparable
interface and the elements' natural ordering should be used.
myList.sort(null); // only if element of the implement Comparable