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;

}





  • 2018-12-07 22:19:33

    修改 Nginx 进程最大可打开文件数(worker_processes和worker_connections)

    worker_processes:操作系统启动多少个工作进程运行Nginx。注意是工作进程,不是有多少个nginx工程。在Nginx运行的时候,会启动两种进程,一种是主进程master process;一种是工作进程worker process。例如我在配置文件中将worker_processes设置为4,启动Nginx后,使用进程查看命令观察名字叫做nginx的进程信息,我会看到如下结果:

  • 2018-12-07 22:55:02

    nginx worker_processes 配置

    据另一种说法是,nginx开启太多的进程,会影响主进程调度,所以占用的cpu会增高, 这个说法我个人没有证实,估计他们是开了一两百个进程来对比的吧。

  • 2018-12-08 11:44:26

    php 时间函数strtotime 使用详解

    这篇文章介绍的内容是关于php 时间函数strtotime 使用详解 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下