Java 比较器(Comparator)是处理对象排序的核心工具,尤其当对象没有自然顺序(如自定义类)或需要多种排序规则时。以下是入门指南,从核心概念到实战示例逐步讲解:
Java 中有两种排序接口,先明确区别:
String、Integer 默认实现),定义默认排序规则,需修改对象类代码。Comparator 是函数式接口(仅一个抽象方法 compare(T o1, T o2)),返回值规则:
-1)1)假设我们有一个 Student 类,需按年龄升序、姓名降序等规则排序,且不想修改 Student 类本身。
Student 类(无 Comparable 实现)class Student {
private String name;
private int age;
private double score;
// 构造器、getter/setter、toString 省略
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
// getter 方法
public String getName() { return name; }
public int getAge() { return age; }
public double getScore() { return score; }
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparatorDemo {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 20, 85.5));
students.add(new Student("Bob", 18, 90.0));
students.add(new Student("Charlie", 20, 88.0));
// 方法1:Lambda 表达式(最常用)
Comparator<Student> ageAscComparator = (s1, s2) -> s1.getAge() - s2.getAge();
// 等价于:Comparator.comparingInt(Student::getAge)
Collections.sort(students, ageAscComparator);
// 输出结果:Bob(18) → Alice(20) → Charlie(20)
students.forEach(s -> System.out.println(s.getName() + ":" + s.getAge()));
}
}
// 方法引用:Student::getName 提取姓名,再按字符串降序(默认升序,reverse 反转)
Comparator<Student> nameDescComparator = Comparator.comparing(Student::getName).reversed();
Collections.sort(students, nameDescComparator);
// 输出:Charlie → Bob → Alice(按姓名首字母降序)
// 链式调用:先按年龄升序,再按分数降序
Comparator<Student> multiComparator = Comparator
.comparingInt(Student::getAge) // 年龄升序
.thenComparing(Comparator.comparingDouble(Student::getScore).reversed()); // 分数降序
Collections.sort(students, multiComparator);
// 不使用 Lambda,用匿名内部类实现 Comparator
Comparator<Student> ageComparator = new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return Integer.compare(s1.getAge(), s2.getAge()); // 推荐用 Integer.compare 避免溢出
}
};
Comparator 提供了大量静态方法简化排序逻辑:
| 方法 | 作用 | 示例 |
|---|---|---|
comparing(Function) |
按对象的某个属性升序 | Comparator.comparing(Student::getAge) |
comparingInt/Long/Double |
按基本类型属性升序(避免装箱) | Comparator.comparingInt(Student::getAge) |
reversed() |
反转当前排序规则 | comparator.reversed() |
thenComparing(Comparator) |
多条件排序(次要规则) | comparator.thenComparing(...) |
o1 - o2:若 o1 和 o2 是 int 且可能溢出(如 o1=2^31-1, o2=-1),结果会错误。推荐用 Integer.compare(o1, o2)。Comparable 和 Comparator:前者是对象自身的“默认排序”,后者是外部“定制排序”。Collections.sort vs List.sort:Java 8 后 List 有默认方法 sort(Comparator),可直接调用:students.sort(ageAscComparator)。Comparator 接口实现比较逻辑(优先 Lambda 或 Comparator 静态方法,简洁)。Collections.sort(list, comparator) 或 list.sort(comparator) 排序。通过以上示例,你可以快速掌握 Comparator 的基本用法,后续可尝试更复杂的场景(如排序 Map 的键值对、自定义复杂对象的多维度排序)。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。