public void test() throws CloneNotSupportedException {
List<TestAddAll> list1 = new ArrayList<>();
List<TestAddAll> list2 = new ArrayList<>();
for(int i=0;i<5;i++){
TestAddAll testAddAll= new TestAddAll();
testAddAll.setAge(i);
testAddAll.setName("name"+i);
list1.add(testAddAll);
}
for(int i=5;i<10;i++){
TestAddAll testAddAll= new TestAddAll();
testAddAll.setAge(i);
testAddAll.setName("name"+i);
list2.add(testAddAll);
}
cloneList(list1,list2);
for (TestAddAll integer : list1) {
System.out.println("姓名="+integer.getName()+",年龄="+integer.getAge());
}
}
static void cloneList(List<TestAddAll> list1,List<TestAddAll> list2) throws CloneNotSupportedException {
long start = System.currentTimeMillis();
//list1.addAll(list2);
for (TestAddAll integer : list2) {
list1.add(integer);
//list1.add(integer.clone());
}
list2.get(0).setAge(100);
long end = System.currentTimeMillis();
//System.out.println(end-start);
}
class TestAddAll implements Cloneable, Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public TestAddAll clone() throws CloneNotSupportedException {
TestAddAll testAddAll= (TestAddAll) super.clone();
return testAddAll;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
将list2的数据通过遍历的方式add到list1集合中,此时修改集合2的一个对象将其年龄改为100,此时list1的对象的年龄也会变成100,。
原因 :集合的add操作知识将这个对象的引用放到这个集合中而已,此时list1添加的list2的对象和list2中的对象指向的是堆里的同一个对象,所以当list2中的对象发生变化时,list1中的对象也会相应发生变化。
解决办法:
如果不想让list2的对象在对list1中的对象数据产生影响,可以使用拷贝的方式,对集合中的类进行clone,生成新的对象,此时两者之间的对象就不会再互相影响,避免不可控。
测试demo,TestAddAll 实现cloneAble接口,然后重写object方法,调用父类Object的Clone()方法,创建新的TestAddAll对象,最后将cloneList遍历list1.add(integer);改为list1.add(integer.clone());
static void cloneList(List<TestAddAll> list1,List<TestAddAll> list2) throws CloneNotSupportedException {
long start = System.currentTimeMillis();
//list1.addAll(list2);
for (TestAddAll integer : list2) {
//list1.add(integer);
list1.add(integer.clone());
}
list2.get(0).setAge(100);
long end = System.currentTimeMillis();
//System.out.println(end-start);
}
测试结果