這屬於我在開發中碰過的坑 ,容器中存放者對象,當clear()的時候,出現的奇葩問題。好了,直接看代碼:
package com.DataType.yinyong; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class TestMethod { //我總結了一下,因為實際開發中涉及到代碼層級較深,所以有時候會不容易看出問題 public static void main(String[] args) { TestMethod testMethod =new TestMethod(); List<Map<String, List<Object>>> resultMaps = new ArrayList<Map<String, List<Object>>>(); resultMaps.add(testMethod.getList()); testMethod.testXunHuan(resultMaps); } public void testXunHuan(List<Map<String, List<Object>>> resultMaps) { for (Map<String, List<Object>> resultMap : resultMaps) { int resultNum = 0; List<Object> result = resultMap.get("r1"); resultMap.remove("r1"); if (result == null) continue; resultNum = result.size(); if (resultNum <= 0) { continue; } for (int i = 0; i < result.size(); i++) { Object o = result.get(i); } result.clear(); System.out.println("雖然 我修改的result是指向r1,但是我的map內的另外一個值 :"+resultMap.get("r12")); } } public Map<String, List<Object>> getList() { Map<String, List<Object>> resultMap = new HashMap<String, List<Object>>(); //下面我提供一個List<Object>,並且讓resultMap中不同的key引用相同的值 Map<String, List<Object>> srcMap = new HashMap<String, List<Object>>(); List<Object> srcList = new ArrayList<Object>(); for(int i = 0 ; i < 10;i++){ srcList.add("count"); } srcMap.put("key1", srcList); srcMap.put("key2", srcList); //下面我聲明一個新的list用來 List<Object> result = srcMap.get("key1"); resultMap.put("r1", result); List<Object> result2 = srcMap.get("key2"); resultMap.put("r12", result2); System.out.println("resul實際上是一個"+(result ==result2) ); return resultMap; } }
輸出結果:
總結 :
1,java中是弱化了引用還是傳值的概念,也不需要考慮指針。
2, 但有些時候,特別是容器內還是需要注意一下,有可能Map中兩個key指向的value是同一個對象,這時候,當你選擇拿到一個值 clear(),就會出現錯誤
3, 於是你可以采用兩種方式解決這一問題
① :如果不去clear(),的確不會對其他數據產生影響,但是會造成內存消耗大,實際開發不可取(實際開發中不可能只有這兩個鍵值對)
② :可以選擇copy一下數組,但是同樣的原因導致不可取(注意collections.copy()方法是如何使用的)
public Map<String, List<Object>> getList() { Map<String, List<Object>> resultMap = new HashMap<String, List<Object>>(); //下面我提供一個List<Object>,並且讓resultMap中不同的key引用相同的值 Map<String, List<Object>> srcMap = new HashMap<String, List<Object>>(); List<Object> srcList = new ArrayList<Object>(); for(int i = 0 ; i < 10;i++){ srcList.add("count"); } List<Object> srcList1 = new ArrayList<Object>(); Collections.addAll(srcList1, new Object[srcList.size()]); Collections.copy(srcList1, srcList);//collection.copy(dest,src)方法需要dest的size大於等於src、屬於深copy srcMap.put("key1", srcList); srcMap.put("key2", srcList1); //下面我聲明一個新的list用來 List<Object> result = srcMap.get("key1"); resultMap.put("r1", result); List<Object> result2 = srcMap.get("key2"); resultMap.put("r12", result2); System.out.println("resul實際上是一個List么"+(result ==result2) ); return resultMap; }
4;最終我決定,每次clear之前,先去判斷是否存在有其他key用到
public void testXunHuan(List<Map<String, List<Object>>> resultMaps) { for (Map<String, List<Object>> resultMap : resultMaps) { int resultNum = 0; List<Object> result = resultMap.get("r1"); resultMap.remove("r1"); if (result == null) continue; resultNum = result.size(); if (resultNum <= 0) { continue; } for (int i = 0; i < result.size(); i++) { Object o = result.get(i); } boolean isExistSame =false; Iterator< List<Object>> ite= resultMap.values().iterator(); while(ite.hasNext()){ if(ite.next().equals(result)){ isExistSame = true; break; } } //只有不存在相同值,才可以刪除 if(!isExistSame){ result.clear(); } System.out.println("雖然 我修改的result是指向r1,但是我的map內的另外一個值 :"+resultMap.get("r12")); } }
參考:
由java中深度復制一伸出Collections.copy的使用