`
月亮不懂夜的黑
  • 浏览: 151617 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

list对象复制问题

阅读更多

Java中的List.addAll复制对象

测试代码

import java.util.ArrayList;
import java.util.List;

/** 
* @author  yannis
* @date create time:2016年10月31日 上午11:10:31 
* @version 1.0 
* @parameter  
* @since  
* @return  
*/

public class Demo {
	public static void main(String[] args) {
		List<Person> list1 = new ArrayList<Person>();
		list1.add(new Person("li","2", 23));
		list1.add(new Person("wang","1", 30));
		list1.add(new Person("zhang","2", 40));
		list1.add(new Person("hu","2", 35));
		list1.add(new Person("chen","1", 60));
		
		List<Person> list2 = new ArrayList<Person>();
		list2.addAll(list1);
		list2.get(0).setName("hanmeimei");
		
		list1.get(1).setName("kkkk");

		for(Person person:list1){
			System.out.println(person.name);
		}
		
		for(Person person:list2){
			System.out.println(person.name);
		}
	}
	
	
	static class Person{
		private String name;
		private String sex;
		private Integer age;
		
		public Person(String name, String sex, Integer age) {
			super();
			this.name = name;
			this.sex = sex;
			this.age = age;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getSex() {
			return sex;
		}
		public void setSex(String sex) {
			this.sex = sex;
		}
		public Integer getAge() {
			return age;
		}
		public void setAge(Integer age) {
			this.age = age;
		}
		
	}
}

 通过测试发现,无论此时修改list1,或者list2 都会影响到两个list.运行结果如下

hanmeimei
kkkk
zhang
hu
chen
hanmeimei
kkkk
zhang
hu
chen

 

 由此可见,使用list.addAll只是把后者的对象的地址指向复制给了前面的list。所以造成一改全改

0
1
分享到:
评论
2 楼 月亮不懂夜的黑 2016-11-08  
cxjhiueannn 写道
查看addAll方法的实现其实并不是将后者的引用对象赋值给前面的list.
之所以会出现一改全改是因为两个list里面所存的对象是指向的同一个对象。
就像 Object obj = new Object();Object obj2 = obj;一样。如果你需要复制后分开 你需要在复制对象的时候克隆对象,就像Object obj = new Object(); Object obj2 = obj.clone();
也就是说如果list没有提供相应的实现 你需要自己实现。

感谢您的指正。确实是 这部分写的有问题。是您说的这个样子,不一样的引用但是指向同样的内存地址。在具体对象做了改动之后,没有修改另一个对其的引用。这里附上API,
addAll

boolean addAll(Collection<? extends E> c)
添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序(可选操作)。如果在操作正在进行中修改了指定的 collection,那么此操作的行为是不确定的(注意,如果指定的 collection 是此列表,并且它是非空的,则会发生这种情况。)
指定者:
接口 Collection<E> 中的 addAll
参数:
c - 包含要添加到此列表的元素的 collection
返回:
如果此列表由于调用而发生更改,则返回 true
抛出:
UnsupportedOperationException - 如果列表不支持 addAll 操作
ClassCastException - 如果指定 collection 的元素的类不允许它添加到此列表
NullPointerException - 如果指定的 collection 包含一个或多个 null 元素,并且该列表不允许 null 元素,或者指定的 collection 为 null
IllegalArgumentException - 如果指定 collection 的元素的某些属性不允许它添加此列表
另请参见:
add(Object)
1 楼 cxjhiueannn 2016-10-31  
查看addAll方法的实现其实并不是将后者的引用对象赋值给前面的list.
之所以会出现一改全改是因为两个list里面所存的对象是指向的同一个对象。
就像 Object obj = new Object();Object obj2 = obj;一样。如果你需要复制后分开 你需要在复制对象的时候克隆对象,就像Object obj = new Object(); Object obj2 = obj.clone();
也就是说如果list没有提供相应的实现 你需要自己实现。

相关推荐

Global site tag (gtag.js) - Google Analytics