map对象拷贝问题

2018-08-23 15:32:18

map对象赋值:

HashMap<String,Object> hm = new HashMap();

HashMap<String,Object> hmCopy = new HashMap();

hm.put("123", 123);

System.out.println(hm.get("123"));

hmCopy = hm;

hmCopy.remove("123");

System.out.println(hm.get("123"));

输出结果:123    null



这种直接赋值属于对象的引用变化,两个变量指向的是同一个对象


//map拷贝putAll方法:

HashMap<String,Object> hm = new HashMap();

HashMap<String,Object> hmCopy = new HashMap();

hm.put("123", 123);

System.out.println(hm.get("123"));

hmCopy.putAll(hm);

hmCopy.remove("123");

System.out.println(hm.get("123"));

输出结果:123   123



map对象深拷贝:


List<Integer> list = new ArrayList<Integer>();

list.add(100);

list.add(200);


HashMap<String,Object> map = new HashMap<String,Object>();

map.put("basic", 100);//放基本类型数据

map.put("list", list);//放对象


HashMap<String,Object> mapNew = new HashMap<String,Object>();

mapNew.putAll(map);


System.out.println("----数据展示-----");

System.out.println(map);

System.out.println(mapNew);

System.out.println("----更改基本类型数据-----");

map.put("basic", 200);

System.out.println(map);

System.out.println(mapNew);

System.out.println("----更改引用类型数据-----");

list.add(300);

System.out.println(map);

System.out.println(mapNew);

System.out.println("----使用序列化进行深拷贝-----");

mapNew = CloneUtils.clone(map);

list.add(400);

System.out.println(map);

System.out.println(mapNew);

输出结果:

----数据展示-----

{basic=100, list=[100, 200]}

{basic=100, list=[100, 200]}

----更改基本类型数据-----

{basic=200, list=[100, 200]}

{basic=100, list=[100, 200]}

----更改引用类型数据-----

{basic=200, list=[100, 200, 300]}

{basic=100, list=[100, 200, 300]}

----使用序列化进行深拷贝-----

{basic=200, list=[100, 200, 300, 400]}

{list=[100, 200, 300], basic=200}




最上面的两条是原始数据,使用了putAll方法拷贝了一个新的mapNew对象,

中间两条,是修改map对象的基本数据类型的时候,并没有影响到mapNew对象。

但是看倒数第二组,更改引用数据类型的时候,发现mapNew的值也变化了,所以putAll并没有对map产生深拷贝。

最后面是使用序列化的方式,发现,更改引用类型的数据的时候,mapNew对象并没有发生变化,所以产生了深拷贝。

上述的工具类,可以实现对象的深拷贝,不仅限于HashMap,前提是实现了Serlizeable接口。



//附克隆方法:

public static <T extends Serializable> T clone(T obj) {

    T cloneObj = null;

    try {

        // 写入字节流

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        ObjectOutputStream obs = new ObjectOutputStream(out);

        obs.writeObject(obj);

        obs.close();


        // 分配内存,写入原始对象,生成新对象

        ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray());

        ObjectInputStream ois = new ObjectInputStream(ios);

        // 返回生成的新对象

        cloneObj = (T) ois.readObject();

        ois.close();

    } catch (Exception e) {

        e.printStackTrace();

    }

    return cloneObj;

}





  • 2019-11-26 13:36:28

    Vue组件命名找不到的问题以及如何给vue组件命名

    首先,Vue 会将 template 中的内容插到 DOM 中,以方便解析标签。由于 HTML 标签不区分大小写,所以在生成的标签名都会转换为小写。例如,当你的 template 为 <MyComponent></MyComponent> 时,插入 DOM 后会被转换为 <mycomponent></mycomponent>。 然后,通过标签名寻找对应的自定义组件。匹配的优先顺序从高到低为:原标签名、camelCase化的标签名、PascalCase化的标签名。例如 <my-component>会依次匹配 my-component、myComponent、MyComponent。camelCase 和 PascalCase 的代码

  • 2019-11-28 11:00:35

    Vue子组件调用父组件的方法

    下面有三种方法,我自己重点推荐第一种,毕竟这种简单粗暴好用好理解,不过这个有一个弊端,再组件嵌套组件的时候,尤其是用第三方组件里面调用自己的子组件的时候,其实已经是孙子组件了,这个时候就要parent.parent。。。。,这样就不好了,我们就得考虑其他方法了,具体怎么判断是父组件,还是爷爷组件,我会单独出一篇文章讲述。

  • 2019-11-29 13:04:47

    计算一个多边形的重心点坐标(准确版)

    在之前的 《如何判断一个多边形是否合法》 一文中有提到,用无人机规划飞行路线前,往往需要框选一个多边形的区域。 而在地图控件上显示这个多边形区域时,往往会遇到这样一个需求:需要把所要测绘的多边形区域移动到地图中心。 实现这个需求的基本思路就是:获取到多边形区域的重心点坐标,然后利用地图控件的 setCenter方法,就可以把地图的显示中心移动到多边形区域重心了。那么问题来了,如何求出一个多边形的重心点坐标呢?

  • 2019-11-29 13:06:27

    如何判断一个多边形是否合法

    利用无人机对一片区域进行测绘前,我们会先在地图上框选一个区域,然后再规划飞行的路线,而需要测绘的这片区域往往是一个多边形。在 MeshKit 中,我们加入了多边形区域的编辑功能,其中就涉及判断用户所编辑出来的多边形是否合法的问题。

  • 2019-11-29 13:47:22

    百度地图做电子围栏总结

    在地图上画出围栏,设置围栏信息后保存,生成围栏列表。全选时,地图视野可看到全部的围栏区域,单独勾选会调整地图视野到当前勾选的围栏。围栏区域的中心点要显示围栏名称。

  • 2019-11-29 13:50:29

    图片连接处出现白线

    block导致,只要父元素设置font-size:0或者设置img display: block; 便可。但是我设置了没有用,这条线不是所有的机型都有,而且页面滚动之后又消失,我琢磨半天,各种尝试,发现把图片高度减少(增加)1px就解决了。因为我们的项目是用postcss-px-to-viewport,我每张图片都是设置高度的,应该是数值转换出现偏差。