Java 集合框架是數據結構在語言層面的標準化實現。本文系統梳理接口體系、核心實現類、經典數據結構(Vector、Stack、Hashtable 等)、泛型機制,並提供豐富代碼示例驗證行為差異。
一、集合框架總覽
三大支柱
- 接口:定義抽象數據類型(Collection、List、Set、Map 等),層次化組織
- 實現類:具體數據結構(ArrayList、HashMap、TreeSet 等),可復用
- 算法:多態的靜態方法(排序、搜索、打亂等),在 Collections 類中
核心接口繼承圖
Collection (根接口)
├── List (有序、可重複) → ArrayList, LinkedList, Vector, Stack
├── Set (無序、不可重複) → HashSet, LinkedHashSet, TreeSet
└── Queue (隊列) → PriorityQueue, ArrayDeque
Map (鍵值映射,不繼承 Collection)
├── HashMap, LinkedHashMap, TreeMap, Hashtable, Properties
二、主流實現類深度對比
List 族系
| 類 | 底層結構 | 特點 | 適用場景 |
| ArrayList | 動態數組 | 隨機訪問快(O(1)),擴容1.5倍,非同步 | 讀多寫少、需索引訪問 |
| LinkedList | 雙向鏈表 | 首尾增刪O(1),訪問O(n),非同步 | 頻繁首尾操作、隊列/棧 |
| Vector | 動態數組 | 同步(線程安全),擴容2倍,較重 | 遺留代碼,新代碼首選 ArrayList + 同步包裝 |
| Stack | 繼承 Vector | LIFO,push/pop/peek/search | 簡單棧需求,建議用 ArrayDeque 替代 |
Set 族系
| 類 | 底層結構 | 特點 | 順序保證 |
| HashSet | HashMap | 增刪查極快,非同步 | 無序,可能變化 |
| LinkedHashSet | HashMap + 雙向鏈表 | 維護插入順序 | 插入順序 |
| TreeSet | 紅黑樹 | 自然序/定制序,log(n) | 有序(升序) |
Map 族系
| 類 | 底層結構 | 特點 | 線程安全 |
| HashMap | 數組+鏈表/紅黑樹(JDK8) | 高性能,允許 null key/value | 否 |
| LinkedHashMap | HashMap + 雙向鏈表 | 維護插入/訪問順序 | 否 |
| TreeMap | 紅黑樹 | Key 有序 | 否 |
| Hashtable | 數組+鏈表 | 同步,不允許 null | 是(粗粒度) |
| ConcurrentHashMap | 分段鎖/CAS(JDK8) | 高併發,分段/細粒度鎖 | 是(高性能) |
| Properties | 繼承 Hashtable | Key/Value 均為 String,配置文件專用 | 是 |
三、經典數據結構類(Java 1.0 遺產,了解即可)
- Enumeration:早期迭代器,
hasMoreElements()/nextElement(),已被 Iterator 取代
- BitSet:位向量,高效存儲布爾標志組,支援邏輯運算
- Vector/Stack:同步動態數組/棧,見上表
- Dictionary/Hashtable:早期鍵值映射,Hashtable 後實現 Map 接口納入集合框架
- Properties:配置屬性專用,支援 load/store 流操作
四、泛型:參數化類型系統
核心優勢
- 類型安全:編譯期捕獲類型錯誤,避免運行期 ClassCastException
- 消除強轉:代碼更乾淨,減少出錯面
- 自文檔化:
List<String> 即說明元素類型
泛型方法
public static <E> void printArray(E[] inputArray) {
for (E element : inputArray) System.out.printf("%s ", element);
System.out.println();
}
// 調用:printArray(new Integer[]{1,2,3}); printArray(new String[]{"A","B"});
有界類型參數
// T 必須實現 Comparable<T>
public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
T max = x;
if (y.compareTo(max) > 0) max = y;
if (z.compareTo(max) > 0) max = z;
return max;
}
泛型類
public class Box<T> {
private T t;
public void add(T t) { this.t = t; }
public T get() { return t; }
}
// 使用:Box<Integer> intBox = new Box<>(); intBox.add(10);
通配符
| 語法 | 含義 | 適用場景 |
<?> | 無界通配符,所有具體類型的父類 | 僅需 Object 方法操作 |
<? extends T> | 上界通配符,T 及其子類(生產者) | 只讀取,不可寫入 |
<? super T> | 下界通配符,T 及其父類(消費者) | 只寫入,讀取僅得 Object |
// PECS 原則:Producer Extends, Consumer Super
public void getData(List<?> data) { ... } // 只讀
public void getNumber(List<? extends Number> data) { ... } // 只讀 Number 及子類
public void addNumbers(List<? super Integer> data) { ... } // 寫入 Integer 及父類
五、實戰代碼驗證
文中包含完整可運行示例:
myArrayList:三種遍歷(foreach、toArray、Iterator)
mymap:四種 Map 遍歷(keySet、entrySet+iterator、entrySet+foreach、values)
myEnumeration:Vector + Enumeration 遍歷
myBitset:位集合邏輯運算
myVector:動態擴容演示
myStack:棧操作 push/pop/peek
myHashTable:Hashtable 基本操作
myProperties:屬性文件讀寫
GenericTest:通配符上下界演示
總結
集合框架將數據結構標準化、API 統一化;泛型將類型約束前置到編譯期。實際開發中:
- 優先使用集合框架標準接口(List、Set、Map)聲明變量
- 根據性能特徵選擇實現類(ArrayList vs LinkedList,HashMap vs TreeMap)
- 泛型盡量具體化,善用通配符實現 API 靈活性與類型安全平衡
- 遺留類仅用於維護舊代碼,新代碼首選現代集合框架