java.util.Collections.copy():列表List浅拷贝
今天同事问我怎样将一个列表(list1)拷贝到另一个列表(list2),然后修改新的列表(list2)不会影响到旧的列表(list1),想了一想,这是深拷贝啊。
可是,除了循环new还有别的办法吗,想了又想,自己也是啥都不懂啊,赶紧百度学习一下,于是就找到了java.util.Collections.copy(),一开始还以为这个是个深拷贝呢,没想到还是个浅拷贝。虽然还没找到深拷贝的方法去解决同事的问题,但还是要学习一下这个浅拷贝,毕竟也是有用滴。
先写个单元测试试一下:
@Test
public void testCollectionsCopy() {
List<String> srcList = new ArrayList<>();
srcList.add("张三");
srcList.add("李四");
srcList.add("王五"); List<String> 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 <T> 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 ||
(src instanceof RandomAccess && dest instanceof RandomAccess)) {
for (int i=0; i<srcSize; 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<srcSize; 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塞一些空对象就完事了。
@Test
public void testCollectionsCopy() {
List<String> srcList = new ArrayList<>();
srcList.add("张三");
srcList.add("李四");
srcList.add("王五"); List<String> 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);
}
}

这里可以发现,给descList指定容量好像并没有什么用,因为ArrayList是可变动态数组队列(底层实现是Array数组),长度会随着实际元素个数自动增大,那么到底是有什么用呢?(保留疑问,这个要看看Java的集合恶补一下知识啦,或者有没有大佬告诉我一下啊)
也可以中JDK7中新增加的方法Array.asList()来实现,即数组转List。
@Test
public void testCollectionsCopy() {
List<String> srcList = new ArrayList<>();
srcList.add("张三");
srcList.add("李四");
srcList.add("王五"); List<String> descList = Arrays.asList(new String[srcList.size()]);
System.out.println(descList.size()); Collections.copy(descList, srcList); for (String desc : descList) {
desc = desc + "是笨蛋";
System.out.println(desc);
}
}

其实也可以用addAll()。
@Test
public void testCollectionsCopy() {
List<String> srcList = new ArrayList<>();
srcList.add("张三");
srcList.add("李四");
srcList.add("王五"); List<String> descList = new ArrayList<>();
descList.addAll(srcList);
System.out.println(descList.size()); for (String desc : descList) {
desc = desc + "是笨蛋";
System.out.println(desc);
}
}
嘻嘻,就这些了,接着找找深拷贝的知识吧,顺便还要总结下浅拷贝和深拷贝的知识呢。
"愿你既可以安于朝九晚五,波澜不惊;又能随时出发,踏浪远航。"
java.util.Collections.copy():列表List浅拷贝的更多相关文章
- java.util.Collections.copy()方法注意点
今天发现单独的将一个ArrayList的对象添加到另外一个ArrayList的时候,总是源列表和目的列表相同的内存地址.原因如下: 偶然看到了Collections的copy(List desc,Li ...
- 要点Java20 java.util.Collections
java.util.Collections 集合帮助类 演示样例程序(JUnit演示) 排序 @Test public void testSort() { List<Integer> de ...
- 集合-强大的集合工具类:java.util.Collections中未包含的集合工具
任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collections包含的工具方法.Guava沿着这些路线提供了更多的工具方法:适用于所有集合的静态方法.这是Guava最流行和成熟 ...
- java.util.Collections.synchronizedSet()方法的使用
下面的例子显示java.util.Collections.synchronizedSet()方法的使用 package com.; import java.util.*; public class C ...
- java.util.Collections.unmodifiableMap 示例
1. 概述 public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m) ...
- 类 java.util.Collections 提供了对Set、List、Map进行排序、填充、查找元素的辅助方法。
类 java.util.Collections 提供了对Set.List.Map进行排序.填充.查找元素的辅助方法. 1. void sort(List) //对List容器内的元素排序,排序的规 ...
- 005-guava 集合-集合工具类-java.util.Collections中未包含的集合工具[Maps,Lists,Sets],Iterables、Multisets、Multimaps、Tables
一.概述 工具类与特定集合接口的对应关系归纳如下: 集合接口 属于JDK还是Guava 对应的Guava工具类 Collection JDK Collections2:不要和java.util.Col ...
- [Google Guava] 2.3-强大的集合工具类:java.util.Collections中未包含的集合工具
原文链接 译文链接 译者:沈义扬,校对:丁一 尚未完成: Queues, Tables工具类 任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collections包含的工具方法.G ...
- [Google Guava] 强大的集合工具类:java.util.Collections中未包含的集合工具
转载的,有问题请联系我 原文链接 译文链接 译者:沈义扬,校对:丁一 尚未完成: Queues, Tables工具类 任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collecti ...
随机推荐
- n2
"express-ws": "^3.0.0", "devDependencies": { "socket.io": ...
- ArcMap2Sld:一个将MXD中图层配图样式转换为OGC的SLD文件的开源工具
在一个项目中,用户采用GeoServer做为GIS服务器(原因嘛当然是免费能省钱,经过验证可能还会在性能和稳定性等表现力也有优越性),但是手上收集的数据都是ESRI格式的,这倒不打紧,因为GeoSer ...
- Java面试知识点之设计模式(一)
前言:关于设计模式,在框架中用的比较多.在平常接触最为频繁的估计是单例模式了,因此笔者在此对设计模式相关知识点进行总结. 1.设计模式的种类 总体来说,设计模式分为3大类总共23种: 1)创建型模式, ...
- vue methods 中方法的相互调用
vue在同一个组件内:方法之间经常需要互相调用. methods中的一个方法如何调用methods中的另外一个方法呢? 可以在调用的时候使用 this.$options.methods.test2( ...
- python笔记31-使用ddt报告出现dict() -> new empty dictionary dict(mapping) 问题解决
使用ddt框架生成html报告的时候,出现:dict() -> new empty dictionary dict(mapping) -> new dictionary initializ ...
- Python单元测试框架 unittest详解
一 整体结构概览 unittest原名为PyUnit,是由java的JUnit衍生而来.对于单元测试,需要设置预先条件,对比预期结果和实际结果. TestCase :通过继承TestCase类,我们可 ...
- C#基于wpf编写的串口调试助手
支持数据保存,自定义协议解码等功能 链接:https://pan.baidu.com/s/1zvhcES4QIjpDDJGzth1qOA 提取码:lp2x
- CSAPP:信息的表和处理1
CSAPP:信息的表和处理1 关键点:寻址.内存.磁盘.虚拟地址.物理地址.整型数组. 信息存储中的几个概念整型数据类型无符号数有符号数几个概念有符号数与无符号数之间转换基于栈与基于寄存器的区别 信息 ...
- 转://Oracle 高可用技术与云基础架构
众所周知Oracle云基础架构已经在越来越多的行业里应用.大家了解云基础架构是如何演进的嘛?可能有人会说Oracle高可用技术是组成云架构的基础,那它们的关系是怎么样的?大家又了解Oracle高可用技 ...
- P2708 硬币翻转(简单模拟)
题意:弱鸡,其实题意是1到i都变化.然后把所有的硬币都变到正面. 简单的模拟: 思路:本质就是记录相邻字符的有几组不同,比如11010,则就有3组不同,但是,这样变化出来的字符串是00000,所以需要 ...