首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java HashMap 存儲 List 陷阱:同一引用導致不同 Key 取值相同

     編輯:程式設計疑難解答

問題現象

List<String> list = new ArrayList<>();
Map<String, List<String>> map = new HashMap<>();

list.add("A");
map.put("key1", list);

list.add("B"); // 繼續向同一 list 添加元素
map.put("key2", list);

// 結果:map.get("key1") 和 map.get("key2") 都指向同一個包含 [A, B] 的 List

根本原因

List 是引用類型。 代碼中始終操作同一個 list 對象實例,map.put("key1", list) 和 map.put("key2", list) 存入的都是同一個對象的引用。後續對 list 的任何修改(add、remove、clear),通過任意 Key 獲取到的 Value 都會反映最新狀態。

正確做法:為每個 Key 創建獨立 List 實例

Map<String, List<String>> map = new HashMap<>();

// Key1 對應的獨立列表
List<String> list1 = new ArrayList<>();
list1.add("A");
map.put("key1", list1);

// Key2 對應的獨立列表
List<String> list2 = new ArrayList<>();
list2.add("B");
map.put("key2", list2);

// 現在 map.get("key1") 為 [A],map.get("key2") 為 [B],互不干擾

進階場景:循環中動態構建 Map

Map<String, List<Data>> resultMap = new HashMap<>();

for (Group group : groups) {
    // 關鍵:在循環內部 new 新 List,確保每組數據獨立
    List<Data> dataList = new ArrayList<>(); 
    
    for (Item item : group.getItems()) {
        dataList.add(convert(item));
    }
    
    resultMap.put(group.getId(), dataList);
}

避坑檢查清單

錯誤模式修正
方法外定義 List,循環裡反覆 put將 new ArrayList<>() 移入循環內部
調用工具方法傳入同一 List 實例工具方法內部創建新 List 並返回
使用 Collections.singletonList 以為複製了它返回不可變單例,非獨立副本

總結

Map 存儲的是引用。 若需不同 Key 對應獨立集合,**必須為每個 Key 實例化一個新的集合對象**。這是 Java 引用語義的基礎體現,同樣適用于 Set、Map 等集合嵌套場景。

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