#Java集合 #排序算法 #Comparator #性能优化
方式 | Comparable接口 | Comparator接口 |
---|---|---|
实现位置 | 目标类内部实现 | 独立类或匿名内部类 |
排序逻辑 | 自然排序(固定规则) | 自定义排序(灵活多变) |
使用场景 | 单一默认排序规则 | 多条件动态排序 |
方法 | compareTo(T o) | compare(T o1, T o2) |
public class Student implements Comparable<Student> {
private String name;
private int age;
private double score;
// 构造方法、getter/setter省略
@Override
public int compareTo(Student other) {
// 按年龄升序
return Integer.compare(this.age, other.age);
}
}
// 使用
List<Student> students = new ArrayList<>();
Collections.sort(students); // 自动使用compareTo
// 按分数降序
students.sort((s1, s2) -> Double.compare(s2.getScore(), s1.getScore()));
// 方法引用简化版
Comparator<Student> scoreComparator = Comparator
.comparingDouble(Student::getScore)
.reversed();
students.sort(scoreComparator);
// 先按年龄升序,年龄相同按分数降序
Comparator<Student> complexComparator = Comparator
.comparingInt(Student::getAge)
.thenComparing(Student::getScore, Comparator.reverseOrder());
students.sort(complexComparator);
// 处理可能为null的字段(如name)
Comparator.nullsFirst(Comparator.naturalOrder());
Comparator<Student> nullSafeComparator = Comparator
.comparing(Student::getName,
Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER))
.thenComparingInt(Student::getAge);
// 按成绩等级排序:优秀(>=90) > 良好(>=80) > 及格(>=60) > 不及格
Comparator<Student> gradeComparator = (s1, s2) -> {
int grade1 = getGradeLevel(s1.getScore());
int grade2 = getGradeLevel(s2.getScore());
return Integer.compare(grade1, grade2);
};
private int getGradeLevel(double score) {
if (score >= 90) return 0;
if (score >= 80) return 1;
if (score >= 60) return 2;
return 3;
}
Comparator<Student> chineseComparator = Comparator
.comparing(s -> Collator.getInstance(Locale.CHINA)
.getCollationKey(s.getName()));
// 生成新排序集合(原集合不变)
List<Student> sortedStudents = students.stream()
.sorted(Comparator.comparing(Student::getAge))
.collect(Collectors.toList());
// 并行流优化(大数据量)
List<Student> parallelSorted = students.parallelStream()
.sorted(complexComparator)
.collect(Collectors.toList());
时间复杂度:
Collections.sort()
使用改进的归并排序(平均O(n log n))对象不可变性:
// 正确做法:返回新集合
List<Student> immutableSorted = students.stream()
.sorted(myComparator)
.toList(); // Java 16+
// 错误做法:修改原始集合
students.sort(myComparator); // 直接修改原集合
对象相等性:
问题1:排序后顺序不符合预期
问题2:Java 8+排序特性失效
// 旧版兼容写法
Collections.sort(students, Comparator
.comparing(Student::getDepartment)
.thenComparing(Student::getId));
问题3:大对象集合内存溢出
选择策略:
Comparable
Comparator
代码规范:
// Good:清晰的方法引用
Comparator.comparing(Person::getBirthDate)
// Bad:冗长的Lambda
Comparator.comparing(p -> p.getBirthDate())
工具推荐:
IntelliJ IDEA:自动生成Comparator代码
Google Guava:ComparisonChain
链式比较
public int compareTo(Student other) {
return ComparisonChain.start()
.compare(this.age, other.age)
.compare(other.score, this.score) // 降序
.result();
}
示例数据集测试:
List<Student> testData = Arrays.asList(
new Student("王五", 20, 88.5),
new Student("张三", 22, 92.0),
new Student("李四", 20, 75.5),
new Student(null, 25, 81.0)
);
testData.sort(nullSafeComparator);
// 结果:
// [null, 李四(20,75.5), 王五(20,88.5), 张三(22,92.0)]
通过合理运用这些技巧,您可以在Java中优雅高效地处理各种对象字段排序需求!