TreeMap(紅黑樹),操作複雜度 O(log n)。Comparable 接口。Comparator。String、Integer 等內置類型已實現 Comparable,可直接排序。
Set<String> ts = new TreeSet<>();
ts.add("xyz");
ts.add("abc");
ts.add("rst");
// 輸出: abc, rst, xyz(字典序)
class Teacher implements Comparable<Teacher> {
int num;
String name;
Teacher(String name, int num) { this.name = name; this.num = num; }
@Override
public int compareTo(Teacher o) {
// 先按 num 降序
int result = Integer.compare(o.num, this.num);
// num 相同按 name 升序
if (result == 0) result = this.name.compareTo(o.name);
return result;
}
@Override public String toString() { return "學號:" + num + "\t姓名:" + name; }
}
// 測試
Set<Teacher> set = new TreeSet<>();
set.add(new Teacher("zhangsan", 1));
set.add(new Teacher("lisi", 2));
set.add(new Teacher("wangmazi", 3));
set.add(new Teacher("mazi", 3));
// 輸出: 學號:3 姓名:mazi / 學號:3 姓名:wangmazi / 學號:2 姓名:lisi / 學號:1 姓名:zhangsan
關鍵點:compareTo返回正/負/零分別代表 大於/小於/等於。TreeSet通過它決定插入位置,返回 0 視為重複元素不插入,故需結合次要字段區分。
不修改實體類,或需多種排序規則時使用。
class Teacher2 {
int num; String name;
Teacher2(String name, int num) { this.name = name; this.num = num; }
@Override public String toString() { return "學號:" + num + " 姓名:" + name; }
static class TeacherCompare implements Comparator<Teacher2> {
@Override
public int compare(Teacher2 o1, Teacher2 o2) {
int result = Integer.compare(o1.num, o2.num); // 升序
if (result == 0) result = o1.name.compareTo(o2.name);
return result;
}
}
}
// 使用
TreeSet<Teacher2> ts = new TreeSet<>(new Teacher2.TeacherCompare());
ts.add(new Teacher2("zhangsan", 2));
ts.add(new Teacher2("lisi", 1));
ts.add(new Teacher2("wangmazi", 3));
ts.add(new Teacher2("mazi", 3));
// 輸出: 學號:1 姓名:lisi / 學號:2 姓名:zhangsan / 學號:3 姓名:mazi / 學號:3 姓名:wangmazi
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<E, Object>(comparator));
}
證明 TreeSet 內部持有 TreeMap 實例,Key 為元素,Value 為固定常量 PRESENT。
| 特性 | HashSet | LinkedHashSet | TreeSet |
|---|---|---|---|
| 底層 | HashMap | LinkedHashMap | TreeMap |
| 順序 | 無序 | 插入序 | 排序序 |
| 性能 | O(1) | O(1) | O(log n) |
| 線程安全 | 否 | 否 | 否 |
compareTo 認為兩對象相等,add 會失敗。TreeSet 以紅黑樹實現有序去重,適合「需要排序 + 去重 + 頻繁範圍查詢」場景。自然排序靠 Comparable,定製排序靠 Comparator,二者不可混用。牢記 compareTo 返回 0 == 去重 原則,避免業務數據意外丟失。