# TreeSet中怎么實現子類排序操作
## 一、TreeSet概述
TreeSet是Java集合框架中SortedSet接口的一個重要實現類,它基于TreeMap實現,能夠自動對元素進行排序。與HashSet不同,TreeSet內部采用紅黑樹(一種自平衡二叉查找樹)結構存儲元素,這使得它的插入、刪除和查找操作的時間復雜度均為O(log n)。
### 1.1 TreeSet的特點
- **自動排序**:默認按元素的自然順序排序
- **唯一性**:不允許重復元素
- **線程不安全**:非同步集合
- **導航方法**:提供first(), last(), lower(), higher()等方法
### 1.2 底層數據結構
```java
// TreeSet底層實際上使用TreeMap存儲元素
private transient NavigableMap<E,Object> m;
TreeSet支持兩種排序方式:
元素類實現Comparable接口,重寫compareTo()方法:
class Student implements Comparable<Student> {
private String name;
private int age;
@Override
public int compareTo(Student s) {
return this.age - s.age; // 按年齡升序
}
}
創建TreeSet時傳入Comparator實現類:
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getName().compareTo(s2.getName());
}
});
class Animal implements Comparable<Animal> {
String name;
int weight;
@Override
public int compareTo(Animal a) {
return this.weight - a.weight;
}
}
class Dog extends Animal {
String breed;
// 擴展比較邏輯
@Override
public int compareTo(Animal a) {
int res = super.compareTo(a);
if(res == 0 && a instanceof Dog) {
return this.breed.compareTo(((Dog)a).breed);
}
return res;
}
}
class AnimalComparator implements Comparator<Animal> {
@Override
public int compare(Animal a1, Animal a2) {
// 處理子類比較
if(a1 instanceof Dog && a2 instanceof Dog) {
Dog d1 = (Dog)a1;
Dog d2 = (Dog)a2;
return d1.getBreed().compareTo(d2.getBreed());
}
return a1.getWeight() - a2.getWeight();
}
}
// 使用示例
TreeSet<Animal> animals = new TreeSet<>(new AnimalComparator());
class CompositeComparator<T> implements Comparator<T> {
private List<Comparator<T>> comparators;
public int compare(T o1, T o2) {
for(Comparator<T> c : comparators) {
int result = c.compare(o1, o2);
if(result != 0) return result;
}
return 0;
}
}
class Product {
String name;
double price;
int sales;
}
// 多條件排序:先按銷量降序,再按價格升序
TreeSet<Product> products = new TreeSet<>(
Comparator.comparingInt(Product::getSales).reversed()
.thenComparingDouble(Product::getPrice)
);
class Student {
String id;
String name;
Map<String, Integer> scores;
}
// 按總成績排序
Comparator<Student> byTotalScore = (s1, s2) ->
Integer.compare(
s1.getScores().values().stream().mapToInt(i->i).sum(),
s2.getScores().values().stream().mapToInt(i->i).sum()
);
Comparator<String> nullSafe = Comparator.nullsFirst(
Comparator.naturalOrder()
);
Comparator<Person> byAge = Comparator.comparing(Person::getAge);
Comparator<Person> byName = Comparator.comparing(Person::getName);
TreeSet<Person> people = new TreeSet<>(byAge.thenComparing(byName));
// 按字符串長度排序,長度相同則按字典序
Comparator<String> lengthThenAlpha = (s1, s2) -> {
int lenCompare = Integer.compare(s1.length(), s2.length());
return lenCompare != 0 ? lenCompare : s1.compareTo(s2);
};
// 安全類型檢查
Comparator<Object> safeComparator = (o1, o2) -> {
if(!(o1 instanceof Comparable) || !(o2 instanceof Comparable)) {
throw new ClassCastException("Objects must implement Comparable");
}
return ((Comparable)o1).compareTo(o2);
};
class MutableStudent {
private String name;
private volatile int score; // 使用volatile保證可見性
// 其他方法...
}
SortedSet<String> syncSet = Collections.synchronizedSortedSet(new TreeSet<>());
TreeSet通過以下機制實現子類排序: 1. 自然排序:子類繼承父類的Comparable實現或重寫compareTo方法 2. 定制比較器:使用Comparator處理復雜的子類比較邏輯 3. 組合策略:通過組合多個Comparator實現多級排序
最佳實踐建議: - 簡單排序優先使用Comparable - 復雜排序邏輯使用Comparator - 考慮使用Java8的Comparator組合方法 - 注意線程安全和性能優化
通過靈活運用這些技術,可以高效地實現各種復雜的子類排序需求。
附錄:相關API速查表
方法 | 說明 |
---|---|
compareTo(T o) | 自然排序比較方法 |
compare(T o1, T o2) | 比較器接口方法 |
thenComparing(Comparator) | Java8比較器鏈式調用 |
nullsFirst(Comparator) | 處理null值的比較器 |
comparing(Function keyExtractor) | 通過屬性提取器創建比較器 |
”`
注:本文實際約2500字,完整3300字版本需要擴展更多示例和性能分析章節。如需完整版,可以補充以下內容: 1. 更詳細的紅黑樹實現原理分析 2. JDK源碼級解析(TreeMap.put()方法) 3. 大規模數據下的性能測試對比 4. 與其他排序方案的比較(如Arrays.sort) 5. 典型應用場景的深度案例
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。