使用 Collections.sort() (适用于基本数据类型和自定义对象)
这是最传统、最简单的方法,适用于 Java 8 之前的环境,现在依然非常常用。

a) 排序基本数据类型的包装类 (如 Integer, String)
Collections.sort() 方法可以直接对 ArrayList 中的元素进行自然排序(升序)。
示例:排序 Integer 类型的 ArrayList
import java.util.ArrayList;
import java.util.Collections;
public class SortArrayListExample {
public static void main(String[] args) {
// 1. 创建一个 ArrayList
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(1);
numbers.add(8);
numbers.add(3);
numbers.add(9);
System.out.println("排序前: " + numbers);
// 2. 使用 Collections.sort() 进行升序排序
Collections.sort(numbers);
System.out.println("升序排序后: " + numbers);
}
}
输出:
排序前: [5, 1, 8, 3, 9]
升序排序后: [1, 3, 5, 8, 9]
示例:排序 String 类型的 ArrayList

字符串会按照字典序(lexicographical order)进行排序。
import java.util.ArrayList;
import java.util.Collections;
public class SortStringArrayList {
public static void main(String[] args) {
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Banana");
fruits.add("Apple");
fruits.add("Orange");
fruits.add("Grape");
System.out.println("排序前: " + fruits);
// 使用 Collections.sort() 进行排序
Collections.sort(fruits);
System.out.println("排序后: " + fruits);
}
}
输出:
排序前: [Banana, Apple, Orange, Grape]
排序后: [Apple, Banana, Grape, Orange]
b) 降序排序
如果需要降序排序,可以使用 Collections.reverseOrder()。
import java.util.ArrayList;
import java.util.Collections;
public class SortDescending {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(1);
numbers.add(8);
numbers.add(3);
System.out.println("排序前: " + numbers);
// 使用 Collections.sort() 和 Collections.reverseOrder() 进行降序排序
Collections.sort(numbers, Collections.reverseOrder());
System.out.println("降序排序后: " + numbers);
}
}
输出:

排序前: [5, 1, 8, 3]
降序排序后: [8, 5, 3, 1]
使用 List.sort() 方法 (Java 8+)
从 Java 8 开始,List 接口本身增加了一个 sort() 方法,这使得代码更加面向对象,无需再导入 Collections 类。
它接受一个 Comparator 对象作为参数。
a) 升序排序 (使用 Comparator.naturalOrder())
对于实现了 Comparable 接口的对象(如 Integer, String),可以使用 Comparator.naturalOrder() 来表示自然排序。
import java.util.ArrayList;
import java.util.Comparator;
public class ListSortExample {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(1);
numbers.add(8);
System.out.println("排序前: " + numbers);
// 使用 List.sort() 和 Comparator.naturalOrder() 进行升序排序
numbers.sort(Comparator.naturalOrder());
System.out.println("升序排序后: " + numbers);
}
}
b) 降序排序 (使用 Comparator.reverseOrder())
同样,降序排序可以使用 Comparator.reverseOrder()。
// ... (同上) numbers.sort(Comparator.reverseOrder()); // ...
对自定义对象进行排序
这是最常见也最重要的场景,当你有一个 ArrayList 存放自定义类的对象时,你必须告诉 Java 根据什么规则来排序。
有两种方式:
让自定义类实现 Comparable 接口
这种方式定义了类的“自然排序”规则,一旦实现,任何使用这个类的 Collections.sort() 或 List.sort() 都会默认使用这个规则。
步骤:
- 在你的自定义类中实现
Comparable<T>接口(T是你的类名)。 - 重写
compareTo(T other)方法。- 返回一个负整数 (
this < other) - 返回零 (
this == other) - 返回一个正整数 (
this > other)
- 返回一个负整数 (
示例:按 age 排序 Person 对象
import java.util.ArrayList;
import java.util.Collections;
// 1. Person 类实现 Comparable 接口
class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
// 2. 重写 compareTo 方法,按年龄排序
@Override
public int compareTo(Person otherPerson) {
// this.age < otherPerson.age 返回负数
// this.age == otherPerson.age 返回 0
// this.age > otherPerson.age 返回正数
return this.age - otherPerson.age;
}
}
public class SortCustomObject {
public static void main(String[] args) {
ArrayList<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));
people.add(new Person("David", 25));
System.out.println("排序前: " + people);
// 3. 直接调用 Collections.sort(),它会自动使用 compareTo 方法
Collections.sort(people);
System.out.println("按年龄升序排序后: " + people);
}
}
输出:
排序前: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=35}, Person{name='David', age=25}]
按年龄升序排序后: [Person{name='Bob', age=25}, Person{name='David', age=25}, Person{name='Alice', age=30}, Person{name='Charlie', age=35}]
注意:Bob 和 David 年龄相同,他们的相对顺序在排序后可能保持不变(稳定排序)。
使用 Comparator (更灵活)
如果你不想修改类的定义,或者一个类需要多种排序方式,Comparator 是更好的选择,你可以在需要排序时动态创建比较规则。
方法:
- 使用
Comparator.comparing()来创建Comparator。 - 可以链式调用
.thenComparing()来实现多条件排序。
示例:按 name 排序,name 相同则按 age 排序
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
class Person {
private String name;
private int age;
// ... (构造方法, getter, toString 同上)
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() { return age; }
public String getName() { return name; }
@Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; }
}
public class SortWithComparator {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
people.add(new Person("Charlie", 35));
people.add(new Person("Bob", 20)); // 另一个 Bob
System.out.println("排序前: " + people);
// 使用 Comparator.comparing() 创建比较器
// 先按 name 排序,name 相同,再按 age 排序
Comparator<Person> byNameThenByAge = Comparator
.comparing(Person::getName) // 按名字比较
.thenComparing(Person::getAge); // 如果名字相同,再按年龄比较
// 使用 List.sort() 方法传入比较器
people.sort(byNameThenByAge);
System.out.println("按姓名和年龄排序后: " + people);
}
}
输出:
排序前: [Person{name='Alice', age=30}, Person{name='Bob', age=25}, Person{name='Charlie', age=35}, Person{name='Bob', age=20}]
按姓名和年龄排序后: [Person{name='Alice', age=30}, Person{name='Bob', age=20}, Person{name='Bob', age=25}, Person{name='Charlie', age=35}]
使用 Java 8 Stream 进行排序
Stream 提供了一种函数式的方式来处理集合,排序是其中之一,这种方法不会修改原始 ArrayList,而是返回一个新的已排序的 Stream,你需要将其收集回一个 List。
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class StreamSortExample {
public static void main(String[] args) {
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(1);
numbers.add(8);
numbers.add(3);
System.out.println("原始列表: " + numbers);
// 使用 Stream 进行升序排序,并收集到新的 List 中
List<Integer> sortedNumbers = numbers.stream()
.sorted() // 默认自然排序
.collect(Collectors.toList());
System.out.println("Stream升序排序后: " + sortedNumbers);
// 使用 Stream 进行降序排序
List<Integer> sortedDescending = numbers.stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
System.out.println("Stream降序排序后: " + sortedDescending);
}
}
输出:
原始列表: [5, 1, 8, 3]
Stream升序排序后: [1, 3, 5, 8]
Stream降序排序后: [8, 5, 3, 1]
总结与选择
| 方法 | 适用场景 | 特点 |
|---|---|---|
Collections.sort(list) |
Java 8 之前,或习惯传统写法 | 简单直接,是静态工具方法。 |
list.sort(comparator) |
Java 8+,推荐 | 更面向对象,是 List 接口的方法。 |
Comparable 接口 |
定义类的“自然排序”规则 | 侵入式,一旦定义,排序规则固定,适合一个类只有一种主要排序逻辑的场景。 |
Comparator 接口 |
需要多种排序方式,或不想修改类 | 非侵入式,非常灵活,可以在任何需要的时候定义新的排序规则。推荐使用。 |
Stream.sorted() |
函数式编程风格,需要链式操作 | 不修改原列表,返回新列表,适合在流处理管道中进行排序。 |
最佳实践建议:
- 对于自定义对象排序,强烈推荐使用
Comparator,它更灵活,不污染你的类定义,并且可以轻松实现多条件排序。 - 如果只是对基本数据类型或字符串进行简单的升/降序排序,
List.sort(Comparator.naturalOrder())或List.sort(Comparator.reverseOrder())是非常简洁的选择。 - 如果你的排序逻辑是复杂的多步操作,或者你正在使用函数式编程范式,
Stream是一个很好的选择。
