Java 的集合框架(Java Collections Framework, JCF)是 Java 中用于存儲和操作數據結構的核心庫,提供了豐富的接口和實現類,用于處理不同類型的集合數據。以下是詳細的介紹:
一、集合框架的體系結構
Java 集合主要分為兩大接口:
Collection
接口:存儲單一元素。- 子接口:
List
(有序可重復)、Set
(無序不可重復)、Queue
(隊列)。
- 子接口:
Map
接口:存儲鍵值對(Key-Value)。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-L6KW4Q8y-1742140403056)(https://i.imgur.com/3V7gXQ6.png)]
二、Collection
接口及實現類
1. List
(有序、可重復)
- 特點:元素按插入順序存儲,允許重復。
- 常用實現類:
ArrayList
:- 基于動態數組實現,支持快速隨機訪問(通過索引)。
- 初始容量為 10,擴容時增長 50%(
newCapacity = oldCapacity + oldCapacity >> 1
)。 - 線程不安全,適用于讀多寫少的場景。
LinkedList
:- 基于雙向鏈表實現,插入和刪除效率高(時間復雜度 O(1))。
- 支持隊列(
Queue
)和雙端隊列(Deque
)操作。
Vector
(已過時):- 線程安全的動態數組,所有方法用
synchronized
修飾,性能較差。 - 替代方案:使用
Collections.synchronizedList(new ArrayList<>())
或CopyOnWriteArrayList
(并發場景)。
- 線程安全的動態數組,所有方法用
2. Set
(無序、不可重復)
- 特點:元素唯一,不保證順序。
- 常用實現類:
HashSet
:- 基于
HashMap
實現,元素存儲在鍵的位置(值用PRESENT
對象占位)。 - 依賴
hashCode()
和equals()
保證唯一性。 - 時間復雜度:添加、刪除、查詢均為 O(1)。
- 基于
LinkedHashSet
:- 繼承
HashSet
,內部通過鏈表維護插入順序。 - 適合需要按插入順序遍歷的場景。
- 繼承
TreeSet
:- 基于紅黑樹(
TreeMap
)實現,元素按自然順序或自定義Comparator
排序。 - 時間復雜度:添加、刪除、查詢均為 O(log n)。
- 基于紅黑樹(
3. Queue
(隊列)
- 特點:先進先出(FIFO)或優先級的元素處理。
- 常用實現類:
LinkedList
:可作為普通隊列使用。PriorityQueue
:- 基于堆結構實現,元素按優先級排序。
- 自然順序或通過
Comparator
定義順序。
ArrayDeque
:- 基于循環數組實現的雙端隊列,適合高效的頭尾操作。
三、Map
接口及實現類
- 特點:鍵值對存儲,鍵唯一。
- 常用實現類:
HashMap
:- 基于數組+鏈表/紅黑樹(Java 8+),鍵的哈希值決定存儲位置。
- 允許
null
鍵和null
值,線程不安全。 - 擴容機制:默認容量 16,負載因子 0.75(容量達到閾值時擴容為 2 倍)。
LinkedHashMap
:- 繼承
HashMap
,通過鏈表維護插入順序或訪問順序(LRU 緩存)。
- 繼承
TreeMap
:- 基于紅黑樹實現,鍵按自然順序或自定義
Comparator
排序。
- 基于紅黑樹實現,鍵按自然順序或自定義
Hashtable
(已過時):- 線程安全的哈希表,被
ConcurrentHashMap
取代。
- 線程安全的哈希表,被
ConcurrentHashMap
:- 分段鎖(Java 7)或 CAS + synchronized(Java 8+)實現高并發。
- 推薦替代
Hashtable
用于多線程場景。
四、工具類 Collections
提供對集合的常用操作:
- 排序:
Collections.sort(list)
- 線程安全包裝:
Collections.synchronizedList(list)
- 不可變集合:
Collections.unmodifiableList(list)
- 查找極值:
Collections.max(collection)
五、迭代器 Iterator
- 作用:遍歷集合元素。
fail-fast
機制:- 在遍歷過程中檢測到集合被修改(如
add
/remove
),立即拋出ConcurrentModificationException
。 - 適用于
ArrayList
、HashMap
等非線程安全集合。
- 在遍歷過程中檢測到集合被修改(如
fail-safe
機制:- 遍歷時對原集合的修改不影響迭代器(如
ConcurrentHashMap
的迭代器)。
- 遍歷時對原集合的修改不影響迭代器(如
六、Java 8+ 新特性
- Lambda 表達式與集合:
list.forEach(element -> System.out.println(element));
- Stream API:
list.stream().filter(e -> e > 5).map(e -> e * 2).collect(Collectors.toList());
HashMap
優化:- 當鏈表長度 ≥ 8 時轉換為紅黑樹,提高查詢效率。
七、如何選擇集合類?
- 需要唯一性:
Set
(HashSet
、TreeSet
)。 - 需要有序性:
List
(ArrayList
、LinkedList
)。 - 鍵值對存儲:
Map
(HashMap
、ConcurrentHashMap
)。 - 多線程環境:
ConcurrentHashMap
、CopyOnWriteArrayList
。 - 排序需求:
TreeSet
、TreeMap
。
八、示例代碼
// List 示例
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");// Set 示例
Set<Integer> hashSet = new HashSet<>();
hashSet.add(1);
hashSet.add(2);// Map 示例
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Apple", 10);
hashMap.put("Banana", 20);// 使用 Stream 過濾
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
通過理解集合框架的結構和特性,可以更高效地選擇適合業務場景的數據結構。