目录

Java Collections.copy()报错:Source does not fit in dest

报错原因分析

首先说一下,报错Source does not fit in dest。

在复制List时,使用Collections.copy(dest, src)方法,首先会检查src的大小是否大于dest的大小,如果大于,则报错。

这一点,源码写的很清楚:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
 * Copies all of the elements from one list into another.  After the
 * operation, the index of each copied element in the destination list
 * will be identical to its index in the source list.  The destination
 * list must be at least as long as the source list.  If it is longer, the
 * remaining elements in the destination list are unaffected. <p>
 *
 * This method runs in linear time.
 *
 * @param  dest The destination list.
 * @param  src The source list.
 * @throws IndexOutOfBoundsException if the destination list is too small
 *         to contain the entire source List.
 * @throws UnsupportedOperationException if the destination list's
 *         list-iterator does not support the <tt>set</tt> operation.
 */
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());
        }
    }
}

但是,如果给dest的List设置了大小,比如下面这样,为什么还是报错?

1
2
	List dest = new ArrayList(src.size());
	Collections.copy(dest, src);

实际上,这样传入的size,只分配了内存,却没有定义元素。

如果这时候打印dest的size,得到的是0。

怎么办?

解决

当你百度如何深拷贝List时,你可能会看到以下两种写法

1
2
	List dest = Arrays.asList(new String[src.size()]);
	CollectionUtils.addAll(dest, new Object[src.size()]);

其本质都是把dest撑起来,此时再执行copy就没有问题了。