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>> resultMaps = new ArrayList>>();
        resultMaps.add(testMethod.getList());
        testMethod.testXunHuan(resultMaps);
        
    }

    public void testXunHuan(List>> resultMaps) {
        for (Map> resultMap : resultMaps) {
            int resultNum = 0;
            List 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> getList() {
        Map> resultMap = new HashMap>();
        //下面我提供一个List,并且让resultMap中不同的key引用相同的值
        Map> srcMap = new HashMap>();
        List srcList = new ArrayList();
        for(int i = 0 ; i < 10;i++){
            srcList.add("count");
        }
        srcMap.put("key1", srcList);
        srcMap.put("key2", srcList);
        //下面我声明一个新的list用来
        List result = srcMap.get("key1");
        resultMap.put("r1", result);
        List 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> getList() {
        Map> resultMap = new HashMap>();
        //下面我提供一个List,并且让resultMap中不同的key引用相同的值
        Map> srcMap = new HashMap>();
        List srcList = new ArrayList();
        for(int i = 0 ; i < 10;i++){
            srcList.add("count");
        }
        List srcList1 = new ArrayList();
        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 result = srcMap.get("key1");
        resultMap.put("r1", result);
        List result2 = srcMap.get("key2");
        resultMap.put("r12", result2);
        System.out.println("resul实际上是一个List么"+(result ==result2) );
        return resultMap;
    } 
    
   

  4;最终我决定,每次clear之前,先去判断是否存在有其他key用到

public void testXunHuan(List>> resultMaps) {
        for (Map> resultMap : resultMaps) {
            int resultNum = 0;
            List 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>  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的浅拷贝和深拷贝

 

    

 

你可能感兴趣的:(Java开发中碰到的Map的坑)