今天遇到一个问题:集合中如何将一个集合的元素复制到一个新的集合里面
最先想到的是利用集合工具类的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异常。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐