Java開發中碰到的Map的坑


這屬於我在開發中碰過的坑 ,容器中存放者對象,當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的使用

Java中的深拷貝(深復制)和淺拷貝(淺復制)

漸析java的淺拷貝和深拷貝

 

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM