Bootstrap

Java Map 深拷贝方法

1、JSON.parseObject(JSON.toJSONString(map))

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.SerializationUtils;
 
import java.util.HashMap;
import java.util.Map;
 
public class JSONDemo {
    public static void main(String[] args) {
        Map<String, Object> main = new HashMap<>();
		main.put("name", "main");
        Map<String, Object> sub = new HashMap<>();
        sub.put("name", "sub");
        sub.put("age", 1);
        main.put("sub", sub);
        System.out.println("原值:" + main);
		// 原值:{sub={name=sub,age=1},name=main}

        // JSON方式可以实现深拷贝
        Map<String, Object> newMain1 = JSON.parseObject(JSON.toJSONString(main));
        Map<String, Object> sub1 = (Map<String, Object>) newMain1.get("sub");
        sub1.put("name", "sub1");
        System.out.println("JSON方式深拷贝,不影响原值");
        System.out.println("原值:" + main);
        System.out.println("新对象值:" + newMain1);
		// JSON方式深拷贝,不影响原值
		// 原值:{sub={name=sub,age=1},name=main}
		// 新对象值:{"sub":{"name":"sub1","age":1},"name":"main"}
     
    }
}

2、使用 Apache 的序列化工具类 SerializationUtils

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.SerializationUtils;
 
import java.util.HashMap;
import java.util.Map;
 
public class CloneDemo {
    public static void main(String[] args) {
        Map<String, Object> main = new HashMap<>();
		main.put("name", "main");
        Map<String, Object> sub = new HashMap<>();
        sub.put("name", "sub");
        sub.put("age", 1);
        main.put("sub", sub);
        System.out.println("原值:" + main);
		// 原值:{sub={name=sub,age=1},name=main}

        // SerializationUtils.clone可以实现深拷贝
        // Map 没有实现 Serializable 接口,而 HashMap 实现了,所以必须转换成 HashMap
        Map<String, Object> clone = SerializationUtils.clone((HashMap<String, Object>) main);
        Map<String, Object> sub2 = (Map<String, Object>) clone.get("sub");
        sub2.put("name", "sub2");
        System.out.println("clone方式深拷贝,不影响原值");
        System.out.println("原值:" + main);
        System.out.println("新对象值:" + clone);
		
		//clone方式深拷贝,不影响原值
		//原值:{sub={name=sub,age=1}, name=main}
		//新对象值:{sub={name=sub2,age=1},name=main}
     
    }
}

3、使用对象的序列化进而实现深拷贝

 /**
     * 使用对象的序列化进而实现深拷贝
     * @param obj
     * @param <T>
     * @return
     */
    private <T extends Serializable> T clone(T obj) {
        T cloneObj = null;
        try {
            ByteOutputStream bos = new ByteOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.close();
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            cloneObj = (T) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObj;
    }
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.SerializationUtils;
 
import java.util.HashMap;
import java.util.Map;
 
public class SerializableClone {
    public static void main(String[] args) {
       // Map改为HashMap
        HashMap<String, Object> goods = new LinkedHashMap<>();
        goods.put("name", "可口可乐");
        goods.put("price", 3);
 
        Map<String, Object> childGoods = new HashMap<>();
        childGoods.put("name", "百事可乐");
        childGoods.put("price", 3);
        goods.put("childGoods", childGoods);
 
        System.out.println("可乐原本价格:" + JSON.toJSONString(goods));
		// 可乐原本价格:{"name":"可口可乐","price":3,"childGoods":{"price":3,"name":"百事可乐"}}
 
        Map<String, Object> newGoods = new LinkedHashMap<>();
        // putAll改为clone实现深度拷贝
        newGoods = clone(goods);
        // 可口可乐涨价了
        newGoods.put("price", 4);
        Map<String, Object> newChildGoods = (Map<String, Object>) newGoods.get("childGoods");
        // 百事可乐见势一起涨价
        newChildGoods.put("price", 4);
 
        System.out.println("涨价后原售价:" + JSON.toJSONString(goods));
		System.out.println("涨价后应售价:" + JSON.toJSONString(newGoods));
		// 涨价后原售价:{"name":"可口可乐","price":3,"childGoods":{"price":3,"name":"百事可乐"}}
		// 涨价后应售价:{"name":"可口可乐","price":4,"childGoods":{"price":4,"name":"百事可乐"}}
     
    }
}

;