在 Java 中,TreeSet 是基于红黑树实现的有序集合,默认按照元素的自然顺序(Comparable)排序。如果你需要自定义排序规则,主要有两种方式:
Comparable 接口(自然排序)class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
// 按年龄升序
return Integer.compare(this.age, o.age);
}
@Override
public String toString() {
return name + "(" + age + ")";
}
}
TreeSet<Person> set = new TreeSet<>();
set.add(new Person("Alice", 20));
set.add(new Person("Bob", 18));
set.add(new Person("Tom", 22));
System.out.println(set);
// 输出:[Bob(18), Alice(20), Tom(22)]
✅ 优点:简单
❌ 缺点:排序规则写死在类里,不够灵活
Comparator(推荐,最灵活 ✅)TreeSet<Person> set = new TreeSet<>(
Comparator.comparingInt(p -> p.age)
);
set.add(new Person("Alice", 20));
set.add(new Person("Bob", 18));
set.add(new Person("Tom", 22));
System.out.println(set);
TreeSet<Person> set = new TreeSet<>(
Comparator.comparingInt((Person p) -> p.age)
.thenComparing(p -> p.name)
);
TreeSet<Integer> set = new TreeSet<>(
Comparator.reverseOrder()
);
set.add(1);
set.add(3);
set.add(2);
System.out.println(set); // [3, 2, 1]
TreeSet 判断“是否相同”依赖 compareTo / comparecompare(a, b) == 0 → 认为 a 和 b 相同
❌ 常见错误:
compareTo 只比较部分字段
→ 不同对象被当成相同,导致 add 失败
✅ 建议:
排序字段 + 唯一标识字段(如 id)一起参与比较
Comparator.comparing(Person::getAge)
.thenComparing(Person::getId)
TreeSet 不允许 null(默认)TreeSet<Integer> set = new TreeSet<>();
set.add(null); // NullPointerException
如果一定要支持 null,需要自定义 Comparator 处理:
Comparator.nullsFirst(Comparator.naturalOrder())
| 方式 | 是否推荐 | 说明 |
|---|---|---|
Comparable |
⭐⭐ | 写在类里,规则固定 |
Comparator |
⭐⭐⭐⭐⭐ | 灵活、可扩展、推荐 |
LinkedHashSet |
❌ | 只能保持插入顺序 |
HashSet |
❌ | 无序 |
如果你有具体排序需求(比如对象字段、字符串规则、中文排序、时间排序),可以直接贴代码,我可以帮你写完整的 Comparator 示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。