image.png
Collections 是对 Collection 和 Map 操作的一个工具类的集合
里面包含了很多的静态方法
具体解析到使用的时候可以再查文档

对于copy函数的解析

void copy(List dest,List src) 将 src 中的内容复制到 dest 中
但是拷贝的时候需要注意两个集合的大小,比如以下代码

  1. /**
  2. * Created By Intellij IDEA
  3. *
  4. * @author Xinrui Yu
  5. * @date 2021/12/4 16:09 星期六
  6. */
  7. public class Application {
  8. public static void main(String[] args) throws Exception {
  9. ArrayList list1 = new ArrayList();
  10. ArrayList list2 = new ArrayList();
  11. list1.add(123);
  12. list1.add(456);
  13. list1.add(789);
  14. Collections.copy(list2,list1);
  15. System.out.println(list2);
  16. }
  17. }

看似没什么问题,但是运行会发现:
image.png

查看 copy 这个方法的源代码
image.png

结合之前的知识,不难理解
因为我们初始化第二个 list 的时候,并没有对其执行 add 操作,那么其底层数组的长度其实还是为 0 的,那么自然就会抛出这样一个错误。

第一反应的解决方案是在初始化的时候,就创建一个合适长度的底层数组,比如下面这样:
image.png

翻看源码中对应的构造器,发现了问题
image.png
发现底层源码中并没有对 list 的 size 属性进行修改。

所以这种方法应该也是行不通的
那么我们就需要对 list 进行一个 “撑开”的操作。
image.png
相当于给 list2 填充了 **list1.size()** 个为 **null** 的数据,起到占位的作用。

使用Collections确保线程安全

image.png

其实底层只是在所有的方法上都使用了同步代码块包裹
image.png

  1. package test15;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.util.*;
  5. /**
  6. * Created By Intellij IDEA
  7. *
  8. * @author Xinrui Yu
  9. * @date 2021/12/4 16:09 星期六
  10. */
  11. public class Application {
  12. public static void main(String[] args){
  13. MyThread myThread = new MyThread();
  14. Thread thread1 = new Thread(myThread);
  15. Thread thread2 = new Thread(myThread);
  16. Thread thread3 = new Thread(myThread);
  17. thread1.setName("线程1");
  18. thread2.setName("线程2");
  19. thread3.setName("线程3");
  20. thread1.start();
  21. thread2.start();
  22. thread3.start();
  23. }
  24. }
  25. class MyThread implements Runnable{
  26. private int number = 100;
  27. private List<Integer> list = new ArrayList<>();
  28. private Object object = new Object();
  29. public MyThread() {
  30. list = Collections.synchronizedList(list);
  31. }
  32. @Override
  33. public void run() {
  34. while(true){
  35. synchronized (object){
  36. if(number > 0){
  37. list.add(number);
  38. try {
  39. Thread.sleep(100);
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43. System.out.println(Thread.currentThread().getName() + "加入了数据:" + number);
  44. System.out.println("当前:" + list);
  45. number--;
  46. }else{
  47. break;
  48. }
  49. }
  50. }
  51. }
  52. }