首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 集合框架深度解析 (三):TreeSet、Comparator、泛型完整指南

     編輯:Java 綜合教學

Java 集合框架深度解析 (三):TreeSet、Comparator、泛型完整指南

基於畢向東 Java 基礎教程筆記整理,系統講解 TreeSet 紅黑樹有序集合、兩種排序策略 (Comparable/Comparator)、泛型核心語法 (類/方法/接口/通配符/邊界) 及實戰練習,夯實集合框架核心功力。

一、TreeSet:有序、不重複、紅黑樹實現

1. 基本特性

  • 實現 NavigableSet 接口,底層 TreeMap (紅黑樹)
  • 元素有序:自然順序 (Comparable) 或定製順序 (Comparator)
  • 元素唯一:依據 compareTo/compare 返回 0 判斷
  • 非線程安全,並發環境用 Collections.synchronizedSortedSet 或 ConcurrentSkipListSet

2. 自然順序示例

TreeSet ts = new TreeSet<>();
ts.add("asd"); ts.add("sdfff"); ts.add("abc"); ts.add("Das");
// 輸出:Das, abc, asd, sdfff (按 ASCII 碼順序:大寫 < 小寫)
Iterator it = ts.iterator();
while (it.hasNext()) System.out.println(it.next());

二、自定義對象排序:兩種策略

策略一:實現 Comparable (內部比較器 / 自然順序)

class Student implements Comparable {
    private String name; private int age;
    // 構造器、getter...
    
    @Override
    public int compareTo(Student other) {
        if (this.age != other.age) return Integer.compare(this.age, other.age);
        // 年齡相同按姓名比較,保證唯一性 (compareTo==0 視為重複)
        return this.name.compareTo(other.name);
    }
}

// 使用
TreeSet ts = new TreeSet<>();
ts.add(new Student("wangwu01", 12));
ts.add(new Student("wangwu02", 44));
// 自動按年齡升序、姓名升序排列

關鍵點:compareTo 必須與 equals 一致,主要鍵相同需比較次要鍵,否則視為重複元素無法入集合。

策略二:構造器傳入 Comparator (外部比較器 / 定製順序)

class StrLenComparator implements Comparator {
    @Override public int compare(String s1, String s2) {
        int lenDiff = Integer.compare(s1.length(), s2.length());
        return (lenDiff != 0) ? lenDiff : s1.compareTo(s2);
    }
}
TreeSet ts = new TreeSet<>(new StrLenComparator());
ts.add("qwe"); ts.add("qde"); ts.add("z"); ts.add("cv"); ts.add("wdsea");
// 輸出:z, cv, qde, qwe, wdsea

練習 2:匿名內部類簡化比較器定義

同上,直接在構造器處 `new Comparator<>() { ... }`。

四、泛型:類型安全的編譯時機制

1. 核心優勢

  • 將 ClassCastException 從**運行時**前移到**編譯時**發現
  • 消除強制轉型煩瑣代碼
  • 增強代碼可讀性與 IDE 智能提示

2. 泛型類

// 傳統 Object 方式:運行時才發現類型錯誤
class Tool { private Object obj; ... }

// 泛型類:編譯時約束類型
class Utils {
    private T t;
    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

// 使用:指定具體類型
Utils u = new Utils<>();
Worker w = u.get(); // 無需強轉,類型安全

3. 泛型方法

class Demo {
    // 方法級泛型:不同調用可傳不同類型
    public  void show(T t) { System.out.println("show: " + t); }
    public  void print(Q q) { System.out.println("print: " + q); }
}
new Demo().show(4);      // T 推斷為 Integer
new Demo().print("haha"); // Q 推斷為 String

4. 靜態方法泛型

靜態方法無法訪問類泛型參數,必須在方法上定義:

public static  void staticMethod(T t) { ... } // 修飾符後、返回值前

5. 泛型接口

interface Inter { void show(T t); }
class InterImpl implements Inter {
    public void show(T t) { System.out.println(t); }
}
new InterImpl().show(5);

6. 通配符 ? 與邊界

語法含義典型場景
無限制通配符,相當于 僅調用 Object 方法、打印集合元素
上界通配符:E 或其子類 (只讀場景)Collection.addAll(Collection)、Collections.copy(dest, src) src 參數
下界通配符:E 或其父類 (寫入場景)Comparator、Collections.copy(dest, src) dest 參數

7. PECS 原則 (Producer Extends, Consumer Super)

  • 作為**生產者** (讀取/遍歷) → 用
  • 作為**消費者** (寫入/添加) → 用
  • 既要讀又要寫 → 不用通配符,用具體類型

8. 實戰示例

// 上界:打印 Person 及其子類 (Student) 集合
public static void printPersons(List list) {
    for (Person p : list) System.out.println(p.getName());
    // list.add(new Student()) // 編譯錯誤!不能寫入
}

// 下界:Student 和 Worker 都能用 Person 的比較器
class PersonComparator implements Comparator { ... }
TreeSet ts1 = new TreeSet<>(new PersonComparator()); // OK: PersonComparator 是 Comparator
TreeSet ts2 = new TreeSet<>(new PersonComparator());  // OK: PersonComparator 是 Comparator

五、總結:集合框架核心知識圖譜

Collection
 ├─ List (有序、可重複) → ArrayList, LinkedList, Vector
 ├─ Set (無序、不可重複)
 │   ├─ HashSet (HashMap, O(1))
 │   ├─ LinkedHashSet (鏈表保持插入序)
 │   └─ TreeSet (紅黑樹, 有序) → Comparable / Comparator
 └─ Queue (隊列) → PriorityQueue, ArrayDeque

Map
 ├─ HashMap (數組+鏈表/紅黑樹)
 ├─ LinkedHashMap (插入/訪問序)
 ├─ TreeMap (紅黑樹, 有序) → Comparable / Comparator
 └─ ConcurrentHashMap (分段鎖/CAS)

泛型體系
 ├─ 泛型類/接口/方法
 ├─ 通配符 ? / extends / super
 ├─ PECS 原則
 └─ 類型擦除 (運行時泛型信息丟失)

掌握 TreeSet 紅黑樹特性、Comparable/Comparator 雙策略、泛型編程精髓 (PECS)、類型擦除限制,是 Java 進階開發者處理有序去重、類型安全 API 設計的必備內功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved