为什么 Hashmap 上的浅拷贝没有反映出来
why shallow copy on Hashmap is not reflecting
我创建了地图,添加了一些项目和克隆来演示浅拷贝。克隆后我在旧参考中添加了一个新项目,但项目没有反映到新参考中。
public class Test implements Cloneable {
public static void main(String[] args) {
HashMap<String,String> smap = new HashMap<String,String>();
smap.put("a1","a1");
smap.put("a2","a2");
smap.put("a3","a3");
smap.put("a4","a4");
//SHALLOW COPY
HashMap<String,String> cMap = (HashMap)smap.clone();
cMap.put("b1","bb");
smap.put("a5","55");
System.out.println("orignal_map\t"+smap);
System.out.println("cMap\t"+cMap);
HashMap<String, String> scopyx = new HashMap<String, String>(smap);
System.out.println("S_copy_x:\t"+scopyx);
}
}
浅拷贝是指不适用于在原始对象内部复制对象。也就是说,如果您有一个包含集合的对象并且您克隆了该对象,则该集合本身不会被复制并且可能会在多个实例之间共享:
public class Test implements Cloneable {
private List<String> innerList = new ArrayList<>();
public void addBaz(String baz) {
innerList.add(baz);
}
public List<String> getInnerList() {
return innerList;
}
public void setInnerList(List<String> innerList) {
this.innerList = innerList;
}
public static void main(String[] args) throws CloneNotSupportedException {
Test bar1 = new Test();
bar1.addBaz("baz1");
bar1.addBaz("baz2");
bar1.addBaz("baz3");
System.out.println("bar1 before cloning: " + bar1.getInnerList());
Test cloneBar = (Test) bar1.clone();
System.out.println("clone: " + cloneBar.getInnerList());
bar1.addBaz("baz4");
System.out.println("clone after adding to original: " + cloneBar.getInnerList());
cloneBar.addBaz("cloneBaz1");
System.out.println("bar1 after adding to clone: " + bar1.getInnerList());
}
}
输出为:
bar1 before cloning: [baz1, baz2, baz3]
clone: [baz1, baz2, baz3]
clone after adding to original: [baz1, baz2, baz3, baz4]
bar1 after adding to clone: [baz1, baz2, baz3, baz4, cloneBaz1]
此外,如果您向 HashMap 添加了除 String 之外的其他对象,您会看到,浅拷贝也在那里工作 - 原始映射和克隆映射包含共享对象,因此两个映射的内容可能会改变:
public class Test implements Cloneable {
private String foo;
// getter/setter/toString ...
public static void main(String[] args) {
HashMap<String, Test> map = new HashMap<>();
map.put("a1", new Test("a1"));
map.put("a2", new Test("a2"));
map.put("a3", new Test("a3"));
System.out.println("map before cloning: " + map);
HashMap<String, Test> cmap = (HashMap<String, Test>) map.clone();
System.out.println("clone: " + cmap);
map.put("b1", new Test("b1"));
System.out.println("clone after adding to original: " + cmap);
cmap.put("c1", new Test("c1"));
System.out.println("original after adding to clone: " + map);
map.get("a1").setFoo("new a1");
System.out.println("clone after modifying object inside original: " + cmap);
cmap.get("a2").setFoo("cloned a2");
System.out.println("original after modifying the clone: " + map);
}
}
输出为:
map before cloning: {a1=->a1, a2=->a2, a3=->a3}
clone: {a1=->a1, a2=->a2, a3=->a3}
clone after adding to original: {a1=->a1, a2=->a2, a3=->a3}
original after adding to clone: {a1=->a1, a2=->a2, a3=->a3, b1=->b1}
clone after modifying object inside original: {a1=->new a1, a2=->a2, a3=->a3, c1=->c1}
original after modifying the clone: {a1=->new a1, a2=->cloned a2, a3=->a3, b1=->b1}
我创建了地图,添加了一些项目和克隆来演示浅拷贝。克隆后我在旧参考中添加了一个新项目,但项目没有反映到新参考中。
public class Test implements Cloneable {
public static void main(String[] args) {
HashMap<String,String> smap = new HashMap<String,String>();
smap.put("a1","a1");
smap.put("a2","a2");
smap.put("a3","a3");
smap.put("a4","a4");
//SHALLOW COPY
HashMap<String,String> cMap = (HashMap)smap.clone();
cMap.put("b1","bb");
smap.put("a5","55");
System.out.println("orignal_map\t"+smap);
System.out.println("cMap\t"+cMap);
HashMap<String, String> scopyx = new HashMap<String, String>(smap);
System.out.println("S_copy_x:\t"+scopyx);
}
}
浅拷贝是指不适用于在原始对象内部复制对象。也就是说,如果您有一个包含集合的对象并且您克隆了该对象,则该集合本身不会被复制并且可能会在多个实例之间共享:
public class Test implements Cloneable {
private List<String> innerList = new ArrayList<>();
public void addBaz(String baz) {
innerList.add(baz);
}
public List<String> getInnerList() {
return innerList;
}
public void setInnerList(List<String> innerList) {
this.innerList = innerList;
}
public static void main(String[] args) throws CloneNotSupportedException {
Test bar1 = new Test();
bar1.addBaz("baz1");
bar1.addBaz("baz2");
bar1.addBaz("baz3");
System.out.println("bar1 before cloning: " + bar1.getInnerList());
Test cloneBar = (Test) bar1.clone();
System.out.println("clone: " + cloneBar.getInnerList());
bar1.addBaz("baz4");
System.out.println("clone after adding to original: " + cloneBar.getInnerList());
cloneBar.addBaz("cloneBaz1");
System.out.println("bar1 after adding to clone: " + bar1.getInnerList());
}
}
输出为:
bar1 before cloning: [baz1, baz2, baz3]
clone: [baz1, baz2, baz3]
clone after adding to original: [baz1, baz2, baz3, baz4]
bar1 after adding to clone: [baz1, baz2, baz3, baz4, cloneBaz1]
此外,如果您向 HashMap 添加了除 String 之外的其他对象,您会看到,浅拷贝也在那里工作 - 原始映射和克隆映射包含共享对象,因此两个映射的内容可能会改变:
public class Test implements Cloneable {
private String foo;
// getter/setter/toString ...
public static void main(String[] args) {
HashMap<String, Test> map = new HashMap<>();
map.put("a1", new Test("a1"));
map.put("a2", new Test("a2"));
map.put("a3", new Test("a3"));
System.out.println("map before cloning: " + map);
HashMap<String, Test> cmap = (HashMap<String, Test>) map.clone();
System.out.println("clone: " + cmap);
map.put("b1", new Test("b1"));
System.out.println("clone after adding to original: " + cmap);
cmap.put("c1", new Test("c1"));
System.out.println("original after adding to clone: " + map);
map.get("a1").setFoo("new a1");
System.out.println("clone after modifying object inside original: " + cmap);
cmap.get("a2").setFoo("cloned a2");
System.out.println("original after modifying the clone: " + map);
}
}
输出为:
map before cloning: {a1=->a1, a2=->a2, a3=->a3}
clone: {a1=->a1, a2=->a2, a3=->a3}
clone after adding to original: {a1=->a1, a2=->a2, a3=->a3}
original after adding to clone: {a1=->a1, a2=->a2, a3=->a3, b1=->b1}
clone after modifying object inside original: {a1=->new a1, a2=->a2, a3=->a3, c1=->c1}
original after modifying the clone: {a1=->new a1, a2=->cloned a2, a3=->a3, b1=->b1}