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

Java 集合框架核心:Map 與 Collection 體系深度解析

     編輯:Java 相關知識

集合體系全景圖

Collection (介面)
├── List (有序、可重複、有索引)
│   ├── ArrayList  (動態數組,查快增刪慢,非線程安全)
│   ├── LinkedList (雙向鏈表,增刪快查慢,非線程安全)
│   └── Vector     (同步 ArrayList,線程安全,效能低)
│
└── Set (無序、不可重複、無索引)
    ├── HashSet    (HashMap 底層,非線程安全)
    ├── LinkedHashSet (維護插入順序)
    └── TreeSet    (紅黑樹,自然序/Comparator 排序,非線程安全)

Map (介面,Key-Value,Key 唯一)
├── HashMap       (數組+鏈表/紅黑樹,Key/Value 可 null,非線程安全)
├── LinkedHashMap (維護插入/訪問順序)
├── Hashtable     (同步 HashMap,Key/Value 不可 null,線程安全)
├── TreeMap       (紅黑樹,Key 有序,Key/Value 不可 null,非線程安全)
└── ConcurrentHashMap (分段鎖/CAS,高併發首選)

核心實現差異對比

集合底層結構線程安全有序性Null 支持典型場景
ArrayList動態數組否插入序支援隨機訪問多、末尾增刪
LinkedList雙向鏈表否插入序支援頻繁頭尾增刪、佇列/棧
HashMap數組+鏈表/樹否無序Key/Value 可 null通用 KV 存儲、緩存
TreeMap紅黑樹否Key 自然序Key/Value 不可 null範圍查詢、有序遍歷
ConcurrentHashMapNode[]+CAS/synchronized是 (高併發)無序Key/Value 不可 null多線程環境共享 Map

去重核心機制:equals + hashCode

HashSet/HashMap 判斷重複流程

  1. 計算 hashCode() 確定桶位置。
  2. 桶內遍歷,調用 equals() 比較內容。
  3. hashCode() 相等且 equals() 為 true → 認定重複。

契約:equals() 相等 ⇒ hashCode() 必須相等。違反會導致集合異常 (如放入 Set 後無法找到)。

TreeSet/TreeMap 判斷重複流程

  1. 調用 compareTo() (實現 Comparable) 或 Comparator.compare()。
  2. 返回 0 → 認定相等 (Key 重複)。

實戰代碼示範

public class CollectionDemo {
    public static void main(String[] args) {
        // 1. List 去重 (保留順序)
        List list = Arrays.asList("a", "b", "a", "c", "b");
        List distinct = list.stream().distinct().collect(Collectors.toList());
        // 或 LinkedHashSet
        List distinct2 = new ArrayList<>(new LinkedHashSet<>(list));
        System.out.println("List 去重: " + distinct); // [a, b, c]
        
        // 2. Map Key 覆蓋行為
        Map map = new HashMap<>();
        map.put("name", "張三");
        map.put("name", "李四"); // 覆蓋
        System.out.println("Map 覆蓋: " + map.get("name")); // 李四
        
        // 3. Set 添加重複元素
        Set set = new HashSet<>();
        System.out.println(set.add("A")); // true
        System.out.println(set.add("A")); // false (未添加)
        
        // 4. TreeMap 自動排序
        Map sorted = new TreeMap<>();
        sorted.put("c", 3); sorted.put("a", 1); sorted.put("b", 2);
        System.out.println("TreeMap 順序: " + sorted.keySet()); // [a, b, c]
    }
}

選型決策樹

  1. 需 Key-Value → Map 家族。
    • 高併發 → ConcurrentHashMap
    • 需有序 (Key) → TreeMap
    • 需插入序 → LinkedHashMap
    • 通用 → HashMap
  2. 需 單值集合 → Collection 家族。
    • 需去重 + 無序 → HashSet
    • 需去重 + 插入序 → LinkedHashSet
    • 需去重 + 排序 → TreeSet
    • 可重複 + 隨機訪問 → ArrayList
    • 可重複 + 頻繁首尾操作 → LinkedList

Java 8+ Stream API 加持


// List 去重並排序
list.stream().distinct().sorted().collect(toList());

// List 轉 Map (Key 提取器, Value 提取器, 衝突合併函數)
Map idUserMap = users.stream()
    .collect(toMap(User::getId, u -> u, (v1, v2) -> v1));

// 分組統計
Map cityCount = users.stream()
    .collect(groupingBy(User::getCity, counting()));

避坑指南

  • 作為 Key 的對象必須不可變:修改 Key 內部狀態導致 hashCode 改變,Map 將無法定位。
  • 避免在循環中創建大量集合:復用、預估初始容量 new ArrayList<>(expectedSize)。
  • 遍歷時修改拋 ConcurrentModificationException:用 Iterator.remove()、或收集待刪列表二次處理、或 CopyOnWriteArrayList。
  • Arrays.asList() 返回固定長度 List:不可 add/remove,需 new ArrayList<>(Arrays.asList(...))。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved