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

Java 集合框架深度總結:Collection、List、Set、Map 全體系解析

     編輯:Java 相關知識

Java 集合框架是 Java 開發中最核心、使用頻率最高的 API 之一。本文基於 java.util 包,系統梳理 Collection、List、Set、Map 四大核心體系的繼承關係、核心特性、常用實現類及最佳實踐,並附帶實戰代碼示例,幫助開發者建立完整的集合知識體系。

集合框架整體架構

Java 集合主要集中在兩個包中:

  • java.util:基礎集合框架
  • java.util.concurrent:並發集合,在前者基礎上實現線程安全

java.util 下的集合對象大致分為三大類:

  1. List:有序、可重複,對應 List 接口
  2. Set:無序、不可重複,對應 Set 接口
  3. Map:鍵值對映射,對應 Map 接口

其中 List 和 Set 繼承自 Collection 接口,Map 獨立繼承體系。

Collection 接口核心操作

作為 List 和 Set 的父接口,Collection 定義了通用的集合操作:

分類方法說明
添加add(E e) / addAll(Collection<? extends E> c)添加單個/批量元素
刪除remove(Object o) / removeAll(Collection<?> c) / clear()刪除指定/批量/所有元素
查詢contains(Object o) / containsAll(Collection<?> c) / isEmpty() / size()包含判斷、空判斷、大小統計
轉換toArray() / toArray(T[] a)集合轉數組
遍歷iterator()獲取迭代器

集合遍歷兩種方式

// 方式一:迭代器遍歷(通用,支持刪除操作)
Iterator<Integer> iterator = collection.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
    // iterator.remove(); // 安全刪除
}

// 方式二:增強 for 循環(語法簡潔,僅讀遍歷)
for (Integer value : collection) {
    System.out.println(value);
}

List 接口詳解

List 是數組的動態擴展,特點:

  • 元素有序(插入順序),可通過索引精確控制位置
  • 允許重複元素與 null 值
  • 容量可動態擴展

三大核心實現類對比

實現類底層結構線程安全優點缺點適用場景
ArrayList動態數組否隨機訪問快 O(1)、內存效率高插入刪除慢 O(n)、擴容有開銷讀多寫少、頻繁隨機訪問
LinkedList雙向鏈表否首尾增刪快 O(1)、實現 Deque隨機訪問慢 O(n)、內存開銷大頻繁增刪、棧/隊列場景
Vector動態數組是(synchronized)線程安全性能差、擴容策略固定 2倍避免使用,推薦 Collections.synchronizedList 或 CopyOnWriteArrayList

Vector 示例

Vector<Integer> vector = new Vector<>();
for (int i = 0; i < 5; i++) vector.add(100);
vector.add(null); // 允許 null 和重複
System.out.println(vector); // [100, 100, 100, 100, 100, null]

// Vector 特有方法
System.out.println(vector.firstElement()); // 首元素
System.out.println(vector.lastElement());  // 尾元素
System.out.println(vector.subList(3, 8));  // 子列表視圖

LinkedList 示例(兼具棧/隊列特性)

LinkedList<Integer> list = new LinkedList<>();
// ... 添加元素 ...
System.out.println(list.peek());      // 查看隊首不移除
System.out.println(list.poll());      // 取出並移除隊首
System.out.println(list.pop());       // 棧彈出(同 pollFirst)
list.push(100);                       // 棧壓入(同 addFirst)

Set 接口詳解

Set 存儲唯一元素,無序(除 LinkedHashSet/TreeSet),核心實現:

實現類底層結構有序性線程安全允許 null特點
HashSetHashMap無序否是(1個)性能最好,依賴 hashCode/equals
LinkedHashSetLinkedHashMap插入序否是(1個)維護插入順序,迭代性能略低
TreeSet紅黑樹自然序/定製序否否有序、範圍查詢、O(log n) 操作

HashSet 去重原理深度解析

HashSet 判斷元素相等依賴 hashCode() 和 equals() 契約:

// 自定義類型破壞 equals 契約示例
class MyInteger {
    private Integer value;
    // 固定 hashCode 導致所有對象進同一桶
    public int hashCode() { return 1; }
    // 永遠返回 true 導致所有對象視為相等
    public boolean equals(Object obj) { return true; }
}

Set<MyInteger> set = new HashSet<>();
set.add(new MyInteger(100));
set.add(new MyInteger(100));
set.add(new MyInteger(100));
System.out.println(set.size()); // 輸出 1(視為同一元素)

// 正確實現應保證:
// 1. equals 相等 ⇒ hashCode 必相等
// 2. hashCode 相等 ⇏ equals 必相等(哈希碰撞)

TreeSet 定製排序

// 實現 Comparable 定製降序
class MyInteger2 implements Comparable<MyInteger2> {
    public int value;
    public int compareTo(MyInteger2 o) {
        return o.value - this.value; // 降序:大的排前面
    }
}

TreeSet<MyInteger2> set = new TreeSet<>();
set.add(new MyInteger2(10));
set.add(new MyInteger2(5));
set.add(new MyInteger2(20));
System.out.println(set); // [20, 10, 5] 降序

Map 接口詳解

Map 存儲鍵值對,Key 唯一,Value 可重複。核心實現對比:

實現類底層結構有序性線程安全允許 null Key允許 null Value特點
HashMap數組+鏈表/紅黑樹無序否是(1個)是JDK1.8+ 鏈表轉紅黑樹優化
Hashtable數組+鏈表無序是否否舊類,性能差,不推薦
LinkedHashMapHashMap+雙向鏈表插入序/訪問序否是(1個)是可實現 LRU 緩存
TreeMap紅黑樹Key 自然序/定製序否否是有序 Map、範圍查詢

HashMap 核心參數與擴容機制

  • initialCapacity:初始容量,默認 16(必須是 2 的冪)
  • loadFactor:負載因子,默認 0.75
  • 擴容觸發:size > capacity * loadFactor
  • 擴容策略:容量翻倍,JDK1.8 採用「高位運行」優化重哈希

預估數據量大時,建議指定初始容量避免頻繁擴容:new HashMap<>(expectedSize * 4 / 3 + 1)

HashMap 與 Hashtable null 值差異

Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(null, null);        // 允許
hashMap.put(1, null);           // 允許

Map<Integer, String> hashtable = new Hashtable<>();
hashtable.put(null, null);      // 拋出 NullPointerException
hashtable.put(1, null);         // 拋出 NullPointerException

最佳實踐總結

  1. 優先使用接口類型聲明:List<String> list = new ArrayList<>(); 便於後續替換實現
  2. 指定初始容量:大致知道數據量時,避免擴容開銷
  3. 泛型檢查:編譯期發現類型錯誤,避免運行時 ClassCastException
  4. 並發場景選擇:
    • 高併發讀、低併發寫:CopyOnWriteArrayList / CopyOnWriteArraySet
    • 高併發讀寫:ConcurrentHashMap / ConcurrentSkipListMap / ConcurrentLinkedQueue
    • 需要複合操作原子性:配合鎖或使用原子類
  5. 避免在 foreach 中修改集合:使用 Iterator.remove() 或並發集合
  6. 合理選擇有序/無序:不需要順序時優先 HashSet/HashMap,性能最優

掌握 Java 集合框架的核心在於理解底層數據結構特性與業務場景的匹配。沒有「最好」的集合,只有「最合適」的集合。

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