list集合循环添加对象详解【对象添加重复&&解决办法&&具体分析】

问题:list集合循环添加对象,添加完后遍历list集合发现,对象都一样,都是最后一个对象的值
问题原因:在循环外实例化对象。

解决方法有两种:
1.循环外定义变量,循环内实例化对象赋值
2.循环内定义变量并实例化对象

建议用第一种解决方法,理由:
第一种方法节省大量栈空间内存

代码如下:
public class ListAddObject {

//准备一个Teacher类 只有一个id属性
static class Teacher {
	private String Id;
	
	public String getId() {
		return Id;
	}

	public void setId(String Id) {
		this.Id = Id;
	}

	public String toString() {
		return "Teacher [Id=" + Id + "]";
	}
}

public static void main(String[] args) {
	//list1代码块  最后添加会出错【对象重复】
	{
		List<Teacher> list1 = new ArrayList<>();
		//添加出错原因,在for循环外实例化对象
		Teacher t = new Teacher();
		for (int i = 0; i < 3; i++) {
			t.setId("00" + i);
			list1.add(t);
		}
		System.out.println("list1:" + list1);
		System.out.println("");
	}

	//list2代码块  推荐的解决办法
	{
		List<Teacher> list2 = new ArrayList<>();
		//解决办法1:for循环外定义变量,循环内实例化对象
		Teacher t = null;
		for (int i = 0; i < 3; i++) {
			t = new Teacher();
			t.setId("0" + i);
			list2.add(t);
		}
		System.out.println("list2:" + list2);
		System.out.println("");
	}
	
	//list3  解决办法  不推荐哦
	{
		List<Teacher> list3 = new ArrayList<>();
		for (int i = 0; i < 3; i++) {
			//解决办法2:循环内实例化对象
			Teacher t = new Teacher();
			t.setId("0" + i);
			list3.add(t);
		}
		System.out.println("list3:" + list3);
	}
}

}
运行截图:
在这里插入图片描述
list1是错误添加,list2和list3是解决办法。

然后再具体分析一下,
list1为什么会添加重复的对象
list2为什么会比list3节省大量栈空间
在这里插入图片描述
如图,我们每次实例化一个对象,如:Teacher t = null; t = new Teacher();
Teacher t = null;相当于在栈空间开辟一块内存存放引用地址【这个地址应该是十六进制的一串数字,此处用*代替】
t = new Teacher();相当于引用地址值指向堆空间中的实际值。

对于list1,当我在循环外实例化对象时,就是在栈空间开辟了一块名字为t的内存,指向了堆空间的内存,此时堆空间内存存放值为null。然后,for循环为堆空间内存中的对象赋值,每次循环相当于t指向堆空间。而list集合每次添加的只是对象的引用值,而非堆空间的实际值,所以,每次循环添加的都是栈空间的引用地址值,都是同一个对象,最后一次循环确定了这个对象的值。

对于list3,对象的实例化放在了循环里面,于是,每次循环都会在栈空间重新开辟一块内存空间,循环了多少次,就开辟了多少次空间,显然很浪费,还可能会导致栈空间内存溢出。

所以建议使用list2,将开辟栈空间内存放在循环外面,每次循环只是重新指向一个新的值。

小生才疏学浅,如有不足,恳请各位大佬批评指正。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值