java list的拷贝_java.util.Collections.copy():列表List拷贝

今天同事问我怎样将一个列表(list1)拷贝到另一个列表(list2),然后修改新的列表(list2)不会影响到旧的列表(list1),想了一想,这是深拷贝啊。

可是,除了循环new还有别的办法吗,想了又想,自己也是啥都不懂啊,于是赶紧百度学习一下。

于是找到了java.util.Collections.copy()

赶紧写个单元测试试一下:

@Testpublic voidtestCollectionsCopy() {

List srcList = new ArrayList<>();

srcList.add("张三");

srcList.add("李四");

srcList.add("王五");

List descList = new ArrayList<>(3);

Collections.copy(descList, srcList);for(String desc : descList) {

System.out.println(desc);

}

}

结果报错,悲剧了:java.lang.IndexOutOfBoundsException: Source does not fit in dest。下标越界啊。

赶紧看看java.util.Collections.copy()的源码压压惊。

public static void copy(List super T> dest, List extends T>src) {int srcSize =src.size();if (srcSize >dest.size())throw new IndexOutOfBoundsException("Source does not fit in dest");if (srcSize < COPY_THRESHOLD ||(srcinstanceof RandomAccess && dest instanceofRandomAccess)) {for (int i=0; i

dest.set(i, src.get(i));

}else{

ListIterator super T> di=dest.listIterator();

ListIterator extends T> si=src.listIterator();for (int i=0; i

di.next();

di.set(si.next());

}

}

}

通过看源码,发现这个方法是有目标数组和源数组的元素个数进行比较的操作,如果目标数组的元素个数小于源数组的元素个数,则抛出异常:下标越界。

可是我已经指定了descList的容量为3了呀!难道这个容量不等于实际元素个数吗?

通过打印descList.size()发现,descList的实际元素个数为0。那么这样我就知道,指定的descList容量为3,只是指定了descList当前容纳的元素个数为3,即指定了descList的容纳能力(Capacity)为3,并不代表descList中有了三个实际的元素。初始化时实际元素个数(Size)永远为0,只有在进行add()和remove()等相关操作时,实际元素个数才会发生改变。

好吧,元凶找到了。只要给descList塞一些空对象就完事了。

@Testpublic voidtestCollectionsCopy() {

List srcList = new ArrayList<>();

srcList.add("张三");

srcList.add("李四");

srcList.add("王五");

List descList = new ArrayList<>(3);

descList.add(null);

descList.add(null);

descList.add(null);

descList.add("赵六");

System.out.println(descList.size());

Collections.copy(descList, srcList);for(String desc : descList) {

desc= desc + "是笨蛋";

System.out.println(desc);

}

}

f770be1d26d1a1a9834c569c7a9a5805.png

这里可以发现,给descList指定容量好像并没有什么用,因为ArrayList是可变动态数组队列(底层实现是Array数组),长度会随着实际元素个数自动增大,那么到底是有什么用呢?

也可以中JDK7中新增加的方法Array.asList()来实现,即数组转List。

@Testpublic voidtestCollectionsCopy() {

List srcList = new ArrayList<>();

srcList.add("张三");

srcList.add("李四");

srcList.add("王五");

List descList = Arrays.asList(newString[srcList.size()]);

System.out.println(descList.size());

Collections.copy(descList, srcList);for(String desc : descList) {

desc= desc + "是笨蛋";

System.out.println(desc);

}

}

df84aa8f20f4c3f06b2d0eb7b567fcc8.png

也可以用addAll()先填充浅拷贝的对象,再进行深拷贝。

@Testpublic voidtestCollectionsCopy() {

List srcList = new ArrayList<>();

srcList.add("张三");

srcList.add("李四");

srcList.add("王五");

List descList = new ArrayList<>();

descList.addAll(srcList);

System.out.println(descList.size());

Collections.copy(descList, srcList);for(String desc : descList) {

desc= desc + "是笨蛋";

System.out.println(desc);

}

}

还有好多东西不懂,我的天。。

原文:https://www.cnblogs.com/yanggb/p/10436165.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值