面向对象2-List list中的这个list到底是不是一个List

相信很多人在初学java的时候,都会遇到一个同样的问题,就是当我们认为自己已经把一个list加入到List<List<T>> 中去了,为什么最后结果发现不对。如这个例子。

List<List<Integer>> res = new ArrayList<List<Integer>>();

List<Integer> list = new ArrayList<Integer>();

for (int i = 0; i < 3; i++) {

list.add(i);

res.add(list);

}

return res;

假设,我们想得到的数据是{ {0}, {0, 1}, {0, 1, 2} } 这样的结果,请问这个res是不是得到了这样的结果?

如果不是,

请问,res.size()==?,然后res里的数据是什么样的?

 

首先,这里只通过ArrayList构造器创建了一个List的实例,也就是说整个过程中,只有一个真正意义上的List Object,但是res.size() == 3。

不仅如此,res == { {0, 1, 2}, {0, 1, 2}, {0, 1, 2} };

 

本人在刚开始学习的过程中,难以预计到这样的结果。

其实原因也很简单。在java中,有不同的数据类型。其中,原始数据类型之间是值传递,而其他的数据类型是引用的“值”传递。(Passing reference doesn't apply to java)

而在java中,一个Object或者Array被创建时,将会在堆中分配内存,同时产生一个该Object或者Array的引用变量(reference)的值放在函数的栈内存中。

也就是说,list只是一个相对应类别的引用名称,或者说是一个句柄(handle)。

当res.add(list)发生时,一个引用变量被传入。在for循环中,被传入了三次。即使在传入的过程中,list所指向的Object所包含的内容不同,却是同一个具体的实例,传入的是Object的值。

最终res里包含的就是三次在return位置时,list所指向的Object的值,也就是 {0, 1, 2}。

为了避免这样的结果导致实际工作中的错误,一般而言,

res.add(new ArrayList<Integer>(list));

在加入一个"引用"型变量时,产生一个新的Object来避免问题的出现。

 

List<List<Integer>> res = new ArrayList<List<Integer>>();

List<Integer> list = new ArrayList<Integer>();

for (int i = 0; i < 3; i++) {

list.add(i);

res.add(new ArrayList<Integer>(list));

}

return res;

// res == { { 0 }, { 0, 1 }, { 0, 1, 2} }

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值