Java中排序规则详解
一、排序基础概念
在Java中,排序的核心是比较规则的实现。Java提供了两种主要机制来定义排序规则:
自然排序:通过
Comparable
接口实现定制排序:通过
Comparator
接口实现
1.1 自然排序 (Comparable)
实现原理:对象自身实现 Comparable
接口,定义与其他同类对象的自然顺序
public interface Comparable<T> {int compareTo(T o);
}
返回值规则:
负数:当前对象 < 比较对象
零:当前对象 = 比较对象
正数:当前对象 > 比较对象
示例:自定义Person类实现自然排序
class Person implements Comparable<Person> {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Person other) {// 先按年龄排序,再按姓名排序int ageCompare = Integer.compare(this.age, other.age);return ageCompare != 0 ? ageCompare : this.name.compareTo(other.name);}
}
使用条件:
当对象有"自然顺序"时(如数字大小、字符串字典序)
需要作为TreeSet/TreeMap的键值
需要默认排序行为时
1.2 定制排序 (Comparator)
实现原理:创建独立比较器,为没有实现Comparable的类或需要不同排序规则时提供灵活性
public interface Comparator<T> {int compare(T o1, T o2);
}
示例:创建不同的比较器
// 按姓名排序的比较器
Comparator<Person> nameComparator = (p1, p2) -> p1.getName().compareTo(p2.getName());// 按年龄倒序排序的比较器
Comparator<Person> ageDescComparator = (p1, p2) -> Integer.compare(p2.getAge(), p1.getAge());
使用条件:
需要多种排序规则
无法修改类源码(如第三方库类)
需要临时排序规则
需要特殊排序(如倒序、多字段组合)
二、数组排序方法
2.1 Arrays.sort() 基本用法
// 基本类型数组(自然排序)
int[] numbers = {5, 2, 9, 1};
Arrays.sort(numbers); // [1, 2, 5, 9]// 对象数组(需要实现Comparable)
Person[] people = {...};
Arrays.sort(people);
2.2 使用Comparator定制数组排序
// 按姓名排序
Arrays.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));// 按年龄倒序
Arrays.sort(people, (p1, p2) -> p2.getAge() - p1.getAge());
三、集合排序方法
3.1 Collections.sort()
List<Integer> numbers = Arrays.asList(5, 2, 9, 1);
Collections.sort(numbers); // 自然排序List<Person> people = new ArrayList<>();
Collections.sort(people, Comparator.comparing(Person::getName)); // 定制排序
3.3 SortedSet/TreeSet 自动排序
// 自动按自然顺序排序
Set<Integer> sortedNumbers = new TreeSet<>(Arrays.asList(5, 2, 9, 1));// 使用Comparator定制排序
Set<Person> sortedPeople = new TreeSet<>(Comparator.comparing(Person::getAge).reversed()
);
四、Java 8+ 高级排序技术
4.1 Comparator 工厂方法
Java 8为Comparator接口提供了丰富的静态工厂方法:
方法 | 描述 | 示例 |
---|---|---|
comparing() | 按属性提取键 | Comparator.comparing(Person::getName) |
comparingInt() | 提取int属性 | Comparator.comparingInt(Person::getAge) |
thenComparing() | 次级排序 | comparing(Person::getAge).thenComparing(Person::getName) |
reversed() | 反转顺序 | comparing(Person::getAge).reversed() |
naturalOrder() | 自然顺序 | Comparator.naturalOrder() |
nullsFirst() | null排最前 | Comparator.nullsFirst(comparing(Person::getName)) |
nullsLast() | null排最后 | Comparator.nullsLast(comparing(Person::getName)) |
组合排序示例:
List<Person> sorted = people.stream().sorted(Comparator.comparing(Person::getDepartment).thenComparingInt(Person::getAge).thenComparing(Person::getName, String.CASE_INSENSITIVE_ORDER)).toList();
4.2 方法引用简化
// 传统Lambda
people.sort((p1, p2) -> p1.getAge().compareTo(p2.getAge()));// 方法引用简化
people.sort(Comparator.comparing(Person::getAge));
4.3 Stream API 排序
List<Person> sortedPeople = people.stream().filter(p -> p.getAge() > 18) // 过滤.sorted(Comparator.comparing(Person::getName).reversed()) // 排序.toList();