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;

}





  • 2017-03-27 16:24:26

    laravel,gulp,Browsersync浏览器同步测试

    Browsersync能让浏览器实时、快速响应您的文件更改(html、js、css、sass、less等)并自动刷新页面。更重要的是 Browsersync可以同时在PC、平板、手机等设备下进项调试。您可以想象一下:“假设您的桌子上有pc、ipad、iphone、android等设备,同时打开了您需要调试的页面,当您使用browsersync后,您的任何一次代码保存,以上的设备都会同时显示您的改动”。无论您是前端还是后端工程师,使用它将提高您30%的工作效率。

  • 2017-03-28 09:27:41

    Java中Arrays的asList()方法

    Java中Arrays的asList()方法 可以将 数组转为List 但是,这个数组类型必须是 引用类型的,如果是8中基本数据类型就不可以 原因如下,引用别人的一篇文章:

  • 2017-03-28 10:58:01

    No such property: sonatypeRepo for class:

    这种问题一般是出现在导入一些开源项目的时候。原因为该项目的原作者会把项目发布到maven中央仓库中,所以在gradle中添加了相关的maven发布任务,而发布任务需要配置

  • 2017-04-02 00:42:51

    PHP的pm、pm.max_requests、memory_limit参数优化说明

    pm是来控制php-fpm的工作进程数到底是一次性产生固定不变(static)还是在运行过程中随着需要动态变化(dynamic)。众所周知,工作进程数与服务器性能息息相关,太少则不能及时处理请求,太多则会占用内存过大而拖慢系统。

  • 2017-04-02 00:44:46

    NGINX + PHP-FPM 502 相关事

    NGINX + PHP-FPM 报 502 错误,我想大部分 SA 都遇到过吧。 根据报错的频率,可以分为两种情况,间歇性的502和连续性的502。 这里只讨论第一种情况——间歇性的502。