
Collections 是对 Collection 和 Map 操作的一个工具类的集合
里面包含了很多的静态方法
具体解析到使用的时候可以再查文档
对于copy函数的解析
void copy(List dest,List src) 将 src 中的内容复制到 dest 中
但是拷贝的时候需要注意两个集合的大小,比如以下代码
/*** Created By Intellij IDEA** @author Xinrui Yu* @date 2021/12/4 16:09 星期六*/public class Application {public static void main(String[] args) throws Exception {ArrayList list1 = new ArrayList();ArrayList list2 = new ArrayList();list1.add(123);list1.add(456);list1.add(789);Collections.copy(list2,list1);System.out.println(list2);}}
看似没什么问题,但是运行会发现:
查看 copy 这个方法的源代码
结合之前的知识,不难理解
因为我们初始化第二个 list 的时候,并没有对其执行 add 操作,那么其底层数组的长度其实还是为 0 的,那么自然就会抛出这样一个错误。
第一反应的解决方案是在初始化的时候,就创建一个合适长度的底层数组,比如下面这样:
翻看源码中对应的构造器,发现了问题
发现底层源码中并没有对 list 的 size 属性进行修改。
所以这种方法应该也是行不通的
那么我们就需要对 list 进行一个 “撑开”的操作。
相当于给 list2 填充了 **list1.size()** 个为 **null** 的数据,起到占位的作用。
使用Collections确保线程安全

其实底层只是在所有的方法上都使用了同步代码块包裹
package test15;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.util.*;/*** Created By Intellij IDEA** @author Xinrui Yu* @date 2021/12/4 16:09 星期六*/public class Application {public static void main(String[] args){MyThread myThread = new MyThread();Thread thread1 = new Thread(myThread);Thread thread2 = new Thread(myThread);Thread thread3 = new Thread(myThread);thread1.setName("线程1");thread2.setName("线程2");thread3.setName("线程3");thread1.start();thread2.start();thread3.start();}}class MyThread implements Runnable{private int number = 100;private List<Integer> list = new ArrayList<>();private Object object = new Object();public MyThread() {list = Collections.synchronizedList(list);}@Overridepublic void run() {while(true){synchronized (object){if(number > 0){list.add(number);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "加入了数据:" + number);System.out.println("当前:" + list);number--;}else{break;}}}}}
