TreeSet基于红黑树实现有序集合,默认按自然排序组织元素,如Integer、String等实现Comparable接口的类会自动排序;自定义类需实现Comparable接口并重写compareTo方法以支持自然排序,否则需提供Comparator避免ClassCastException;可通过Comparator实现多种排序方式,如按姓名排序或逆序排列;注意比较逻辑应与equals一致,防止重复判断错误。

在Java中,TreeSet 是一个基于红黑树(Red-Black Tree)实现的有序集合,它能够自动对元素进行排序。默认情况下,TreeSet 会按照元素的自然排序来组织数据,也可以通过自定义比较器实现灵活的排序规则。
TreeSet 的自然排序
当使用 TreeSet 存储实现了 Comparable 接口的类对象时,比如 Integer、String、Double 等,TreeSet 会自动调用这些类的 compareTo() 方法进行排序。
例如:
TreeSetnumbers = new TreeSet<>(); numbers.add(5); numbers.add(2); numbers.add(8); numbers.add(1); System.out.println(numbers); // 输出 [1, 2, 5, 8]
这里的 Integer 类本身就实现了 Comparable 接口,compareTo 方法定义了升序比较逻辑,因此插入后自动按从小到大排列。
立即学习“Java免费学习笔记(深入)”;
如果你添加的类没有实现 Comparable 接口,而你又未提供 Comparator,在运行时会抛出 ClassCastException。
自定义类实现自然排序
为了让自定义类支持自然排序,需要让该类实现 Comparable
例如,有一个 Student 类,希望按年龄升序排序:
class Student implements Comparable{ private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Student other) { return Integer.compare(this.age, other.age); // 按年龄升序 } @Override public String toString() { return name + "(" + age + ")"; } }
使用示例:
TreeSetstudents = new TreeSet<>(); students.add(new Student("Alice", 20)); students.add(new Student("Bob", 18)); students.add(new Student("Charlie", 22)); System.out.println(students); // 输出 [Bob(18), Alice(20), Charlie(22)]
注意:如果多个学生年龄相同,compareTo 返回 0,TreeSet 会认为它们是重复元素,不会重复添加。若需允许同龄学生共存,应在 compareTo 中加入次要排序字段(如姓名)。
使用 Comparator 自定义排序规则
如果不希望修改原类结构,或需要多种排序方式,可以通过传入 Comparator 实现灵活排序。
比如,想让 Student 按姓名字母顺序排序:
TreeSetstudents = new TreeSet<>((s1, s2) -> s1.getName().compareTo(s2.getName()) );
或者使用方法引用更简洁:
TreeSetstudents = new TreeSet<>(Comparator.comparing(Student::getName));
也可以实现逆序:
TreeSetdesc = new TreeSet<>(Comparator.reverseOrder()); desc.add(3); desc.add(1); desc.add(4); System.out.println(desc); // [4, 3, 1]
TreeSet 的排序机制依赖于比较结果的一致性:无论使用自然排序还是比较器,都要求比较逻辑与 equals 方法保持一致(即:如果 a.compareTo(b) == 0 或 comparator.compare(a,b)==0,则 a.equals(b) 应为 true),否则可能引发不符合预期的行为。
基本上就这些。掌握自然排序和自定义比较器的使用,就能灵活控制 TreeSet 中元素的排列顺序。










