今天遇到一个问题:集合中如何将一个集合的元素复制到一个新的集合里面
最先想到的是利用集合工具类的copy()方法,但是它出现了一些问题
首先看看 Collections里面的copy()方法:
copy(List<? super T> dest, List<? extends T> src)
表示将所有元素从一个列表复制到另一个列表中。src是原来列表,dest是新的列表。
public class CollectionsTest {
public static void main(String[] args) {
// 创建一个集合list
ArrayList<Integer> list = new ArrayList<Integer>();
// 给集合中添加元素
list.add(66);
list.add(88);
list.add(126);
list.add(368);
list.add(0);
list.add(-99);
// 创建一个新的集合dest
ArrayList<Integer> dest = new ArrayList<Integer>();
// 把list集合中的元素复制到dest集合中
Collections.copy(dest, list);
System.out.println(dest);
}
}
代码执行结果:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Source does not fit in dest
at java.util.Collections.copy(Collections.java:556)
at com.zxy.java.collection.CollectionsTest.main(CollectionsTest.java:27)
看到程序报错,说下标越界:来源不适合dest
点进去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());
}
}
}
分析它的源码,copy()方法是:
- 得到原来集合的大小, int srcSize = src.size();
- 如果srcSize大于dest.size,将会抛出异常
if (srcSize > dest.size())
throw new IndexOutOfBoundsException(“Source does not fit in dest”);
得出这样的结论:
dest.size()的长度不能小于srcSize();目标列表必须至少与源列表一样长。如果更长,则目标列表中的其余元素不受影响。
修改代码如下:
public class CollectionsTest {
public static void main(String[] args) {
// 创建一个集合list
ArrayList<Integer> list = new ArrayList<Integer>();
// 给集合中添加元素
list.add(66);
list.add(88);
list.add(126);
list.add(368);
list.add(0);
list.add(-99);
// 创建一个新的集合dest
ArrayList<Integer> dest = new ArrayList<Integer>(list.size());
// 打印dest的大小
System.out.println(dest.size());
}
}
这样又出现一个问题,当打印dest的大小的时候,结果为 0;
原因是 这样传入的size参数只是为该大小分配了足够的内存,它实际上没有定义元素。
我们就是为了撑开dest.size的大小 ,这怎么办呢?
造一个长度是原集合大小的数组,元素的个数是size,每个位置是null。
修改代码如下:
public class CollectionsTest {
public static void main(String[] args) {
// 创建一个集合list
ArrayList<Integer> list = new ArrayList<Integer>();
// 给集合中添加元素
list.add(66);
list.add(88);
list.add(126);
list.add(368);
list.add(0);
list.add(-99);
List dest = Arrays.asList(new Integer[list.size()]);
System.out.println("dest集合的大小为: " + dest.size());
// 把list集合中的元素复制到dest集合中
Collections.copy(dest, list);
System.out.println("dest集合为:" + dest);
}
}
代码执行结果:
dest的大小6
dest集合为:[66, 88, 126, 368, 0, -99]
在此说说Arrays.asList()
Arrays是java容器相关操作的工具类,asList()方法将数组转换为集合。
在使用工具类Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,否则会抛出UnsupportOperationException异常。