浅克隆:将新集合每个元素的引用指向原集合对应对象在栈空间的内存地址,所以,原集合修改或删除,克隆的集合随之改变;新集合修改添加会改变引用重新指向其他堆内存地址,删除就直接删除引用。
深克隆:将新集合的元素对象复制,在堆内存中重新开辟空间存一样的内容,一般要对集合中的对象重写clone(),在clone()中返回new的新对象,再add到新集合中,所以新旧集合操作互不影响。
以下为测试代码:
方法多测试看效果,每次只是用部分方法,注释部分方法看起更清晰
ArrayList easyList = new ArrayList();
easyList.add(new Integer(1));
easyList.add(new Integer(2));
easyList.add(new Integer(3));
//浅克隆,移除克隆集合原集合不变
ArrayList clonelist = (ArrayList) easyList.clone();
//移除现集合,原集合不变
//clonelist.remove(easyList.size()-1);
//移除原集合,现集合改变
easyList.remove(1);
//新集合修改不影响原集合
//clonelist.set(0, 99);
sop("浅克隆原集合"+easyList);
sop("浅克隆现集合"+clonelist);
//深克隆,克隆集合中对象,对象要重写clone()
ArrayList deepList = new ArrayList();
deepList.add(new listCloneDemo("java1",1));
deepList.add(new listCloneDemo("java3",3));
deepList.add(new listCloneDemo("java2",2));
ArrayList deepClone = new ArrayList();
//重新new对象加入新集合
for (listCloneDemo listCloneDemo : deepList) {
deepClone.add(listCloneDemo.clone());
}
//移除现集合,原集合不变
//deepClone.remove(2);
//操作现集合,原集合不改变,因为new新对象加入
deepClone.get(1).setNum(100);
//深克隆的好处就是原集合改变对新集合没影响
deepList.remove(0);
sop("深克隆原集合"+deepList);
sop("深克隆现集合"+deepClone);
public static void sop(Object obj) {
System.out.println(obj);
}
class listCloneDemo{
private String str;
private int num;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public listCloneDemo(String str,int num) {
super();
this.num = num;
this.str = str;
}
@Override
public String toString() {
return "listCloneDemo [str=" + str + ", num=" + num + "]";
}
//这个方法不能使返回对象指向this对象的引用,不如直接返回this
@Override
protected listCloneDemo clone(){
listCloneDemo listCloneDemo = new listCloneDemo(this.str, this.num);
return listCloneDemo;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + num;
result = prime * result + ((str == null) ? 0 : str.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
listCloneDemo other = (listCloneDemo) obj;
if (num != other.num)
return false;
if (str == null) {
if (other.str != null)
return false;
} else if (!str.equals(other.str))
return false;
return true;
}
}