zoukankan      html  css  js  c++  java
  • map对象拷贝问题

    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;
    }
  • 相关阅读:
    spring boot集成redis和mongodb实现计步排名
    spring boot + redis 实现网站限流和接口防刷功能
    基于spring-boot-data-jdbc的RowMapper实例的初始化配置,配置内容和实体类的代码由测试类生成
    自定义注解并封装成jar包,实现一般方法和Controller类的入参、出参和执行时间的日志打印
    封装自己的spring-boot-starter实现初始化字典数据和脱敏(windows10+jdk8+idea+spring-boot2.1.5)
    spring boot 集成mybatis的多数据源
    常用工具说明--jsdoc 前端文档输出工具
    常用工具说明--mysql数据库安装
    web前端--实现前后端分离的心得
    资料汇总--Ajax中Put和Delete请求传递参数无效的解决方法(Restful风格)【转】
  • 原文地址:https://www.cnblogs.com/leskang/p/7169233.html
Copyright © 2011-2022 走看看