Jakob Jenkov 2020-10-04
你可以使用 java.util.Collections.sort() 方法对 Java 的 List 集合进行排序。以下两种 List 类型都可以被排序:
ArrayListLinkedList
按自然顺序对对象排序
要对一个 List 进行排序,可以这样做:
List list = new ArrayList();
// 向列表中添加元素
Collections.sort(list);
以这种方式排序时,元素将按照其“自然顺序”(natural order)进行排列。为了让对象具有自然顺序,它们必须实现 java.lang.Comparable 接口。有关 Comparable 接口的更多信息,请参阅 Java Comparable 教程。换句话说,这些对象必须是可比较的,才能确定它们的顺序。
以下是 Comparable 接口的定义:
public interface Comparable<T> {
int compareTo(T o);
}
compareTo() 方法应将当前对象与另一个对象进行比较,并返回一个 int 值。该返回值需遵循以下规则:
- 如果当前对象小于另一个对象,则返回一个负数;
- 如果当前对象等于另一个对象,则返回 0;
- 如果当前对象大于另一个对象,则返回一个正数。
在实现 compareTo() 方法时还有其他一些更具体的要求,但以上是主要规则。详细信息请查阅 Java 官方文档(JavaDoc)。
举个例子,假设你正在对一个包含 String 元素的 List 进行排序。排序过程中,每个字符串会通过某种排序算法(此处不展开)与其他字符串进行比较。每个字符串通过字母顺序来比较自身与其他字符串的大小。因此,如果一个字符串按字母顺序小于另一个字符串,它的 compareTo() 方法就会返回一个负数。
当你在自己的类中实现 compareTo() 方法时,你需要决定这些对象应该如何相互比较。例如,Employee 对象可以按名字、姓氏、薪资、入职年份等任何你认为合理的属性进行比较。
使用 Comparator 对象进行排序
有时,你可能希望按照不同于自然顺序的方式对列表进行排序。或者,你所排序的对象甚至没有自然顺序。在这种情况下,你可以使用 Comparator。有关 Comparator 接口的更多信息,请参阅 Java Comparator 教程。
以下是使用 Comparator 对列表排序的方法:
List list = new ArrayList();
// 向列表中添加元素
Comparator comparator = new SomeComparator();
Collections.sort(list, comparator);
注意,现在 Collections.sort() 方法除了接收 List 外,还额外接收一个 java.util.Comparator 参数。这个 Comparator 会逐一比较列表中的元素。
以下是 Comparator 接口的定义:
public interface Comparator<T> {
int compare(T object1, T object2);
}
compare() 方法用于比较两个对象,应遵循以下规则:
- 如果
object1小于object2,返回一个负数; - 如果
object1等于object2,返回 0; - 如果
object1大于object2,返回一个正数。
同样,compare() 方法的实现还有一些额外要求,但上述是核心规则。更多细节请参考 JavaDoc。
下面是一个比较两个虚构 Employee 对象的 Comparator 示例:
public class MyComparator<Employee> implements Comparator<Employee> {
public int compare(Employee emp1, Employee emp2) {
if (emp1.getSalary() < emp2.getSalary()) return -1;
if (emp1.getSalary() == emp2.getSalary()) return 0;
return 1;
}
}
一种更简洁的写法如下:
public class MyComparator<Employee> implements Comparator<Employee> {
public int compare(Employee emp1, Employee emp2) {
return emp1.getSalary() - emp2.getSalary();
}
}
通过将一个薪资减去另一个薪资,结果会自动为负数、0 或正数。是不是很巧妙?
如果你需要根据多个因素对对象进行比较,可以先按第一个因素(如名字)比较;如果第一个因素相等,再按第二个因素(如姓氏或薪资)比较,依此类推。