02-Collection

image-20230320094428381

Collection => 不支持普通for循环(无index)

  1. List => 有序,不唯一。拓展的API都和index有关
    1. Vector(线程安全)效率低,淘汰
      • 底层为数组,扩容策略2倍
    2. ArrayList(线程不安全):源码类似StringBuilder
      • JDK7底层为数组(饿汉式),构造器数组长度初始化10,扩容策略1.5倍
      • JDK8底层为数组(懒汉式),构造器数组为{},add()数组长度为10,扩容策略1.5倍
    3. LinkedList
      • JDK8底层双向链表
  2. Set => 无序,唯一。无index
    1. HashSet:哈希表
      1. LinkedHashSet:哈希表 + 链表
        • 有序(输入顺序)
    2. TreeSet
      • 有序(自定义顺序)。二叉树。类必须实现Comparator

1. Collection

1. API

/*
 * Collection_API
 *
 * 1. 增加:add(E e), addAll(Collection<? extends E> c)
 * 2. 删除:clear(), remove(Object o)
 * 3. 修改:
 * 4. 查看:iterator(), size()
 * 5. 判断:contains(Object o), equals(Object o), isEmpty()
 */
@Test
public void T1_API() {
    Collection<Object> col = new ArrayList<>();
    // 集合特点:只能存放引用数据类型,不能存基本类型
    // 基本数据类型对应包装类。int => Integer
    col.add(18);
    col.add(12);
    col.add(11);
    col.add(17);

    // 默认.toString()
    System.out.println("col = " + col);

    List<Object> list = Arrays.asList(11, 15, 3, 7, 1);
    col.addAll(list); // 将另一个集合添加入col中
    System.out.println("col = " + col);

    boolean isRemove = col.remove(15);
    System.out.println("删除15 = " + col);

    Collection<Object> col2 = new ArrayList<>();
    col2.add(18);
    col2.add(12);
    col2.add(11);
    col2.add(17);
    Collection<Object> col3 = new ArrayList<>();
    col3.add(18);
    col3.add(12);
    col3.add(11);
    col3.add(17);
    System.out.println("equals: " + col2.equals(col3));
    System.out.println("==: " + (col2 == col3)); // false,地址一定不相等
    System.out.println("contains: " + col3.contains(117));

    col.clear(); // 清空集合
    System.out.println("col.size() = " + col.size());
    System.out.println("col.isEmpty() = " + col.isEmpty());
}














 








 


 












 

 

 

 

2. 遍历

/**
 * 1. 普通fori循环。无index无法进行
 * 2. 增强for循环
 * 3. iterator()
 */
@Test
public void T2_iterator() {
    Collection<Object> col = Arrays.asList(18, 12, 11, 17, "abc", 9.8);

    // 方式1:普通for循环。无index无法进行
    for (int i = 0; i < col.size(); i++) {
        // col.
    }

    // 方式2:增强for循环
    for (Object o : col) {
        System.out.println(o);
    }
    System.out.println("------------------------");

    // 方式3:iterator()
    Iterator<Object> it = col.iterator();
    while (it.hasNext()) {
        System.out.println(it.next());
    }
}










 




 





 




2. List

  • 相较Collection接口,增加有关index抽象方法

1. API

/*
 * List
 *
 * 1. 增加:add(int index, E element)
 * 2. 删除:remove(int index), remove(Object o)
 * 3. 修改:set(int index, E element)
 * 4. 查看:get(int index)
 * 5. fori
 */
@Test
public void T1_API() {
    List<Object> list = new ArrayList<>();
    list.add(13);
    list.add(17);
    list.add(6);
    list.add(-1);
    list.add(2);
    list.add("abc");
    System.out.println(list);

    // 1. add(int index, E element);
    list.add(3, 66);
    System.out.println("add() = " + list);

    // 2. set(int index, E element);
    list.set(3, 77);
    System.out.println("set() = " + list);

    // 3.1. remove(int index);
    list.remove(2);
    System.out.println("remove() = " + list);

    // 3.2. remove(Object o);
    list.remove("abc");
    System.out.println(list);

    // 4. get(int index);
    Object o = list.get(0);
    System.out.println("get(0) = " + o);

    System.out.println("==============================");

    // 5.1. 普通for循环
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));
    }

    System.out.println("==============================");

    // 5.2. 增强for循环(底层为iterator)
    for (Object obj : list) {
        System.out.println(obj);
    }

    System.out.println("==============================");

    // 5.3. 迭代器
    Iterator<Object> it = list.iterator();
    while (it.hasNext()) {
        int next = (int) it.next();
        if (next == 17) {
            it.remove();
        } else {
            System.out.println(next);
        }
    }
    System.out.println(list);
}





















 



 



 



 



 





 






 






 










3. ArrayList

  1. 默认数组长度:10
  2. Object[]扩容策略1.5倍
  3. 懒汉式。add()时,底层数组长度变为10
/**
 * 1. 默认数组长度:10
 * 2. Object[]扩容策略1.5倍
 * 3. 懒汉式。`add()`时,底层数组长度变为10
 */
@Test
public void T2_ArrayList_SC() {
    // 底层数组为{},length为0
    ArrayList<Object> noArgs = new ArrayList<>();
    // add(),Object[].length = 10
    noArgs.add("ooxx");

    // Object[].length = 3
    ArrayList<Object> args = new ArrayList<>(3);
}

1. SC

// 集合创始人承认这个失误,但在后续的版本中没有删除,觉得没必要
// class AbstractList<E> extends AbstractCollection<E> implements List<E>
class _ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    // 1. 底层数组
    transient Object[] elementData;

    // list长度
    private int size;

    private static final Object[] EMPTY_ELEMENTDATA = {};

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    // 2. 默认数组长度
    private static final int DEFAULT_CAPACITY = 10;

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * 无参构造
     */
    public _ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;
    }

    /**
     * 有参构造。指定数组长度
     */
    public _ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
        }
    }

    public boolean add(E e) {
        // 3.1. 确认容量
        ensureCapacityInternal(size + 1);
        elementData[size++] = e;
        return true;
    }

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

    // 3.2. 计算最小容量
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        // 第一次add(),Object[]默认长度10
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {   // {}
            return Math.max(DEFAULT_CAPACITY, minCapacity);       // 10
        }
        return minCapacity;
    }

    // 3.3. 判断是否扩容
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // 最小容量 > Object[]容量
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    // 3.4. 扩容。1.5倍容量
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;

        // Object[]扩容1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);

        // 扩容容量 < 最小容量,取最小长度
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;

        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);

        // old[] => new[]
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0)
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }

    @Override
    public E get(int index) {
        // rangeCheck(index);
        return elementData(index);
    }

    @SuppressWarnings("unchecked")
    E elementData(int index) {
        return (E) elementData[index];
    }

	@Override
    public int size() {
        return size;
    }
}






 









 








 

















 





 






 










 







 









 













 




 




 


4. Vector

  1. 默认底层数组长度:10(饿汉式)
  2. Object[]扩容策略2倍
  3. 所有方法被synchronized修饰
/**
 * 1. 默认底层数组长度:10(饿汉式)
 * 2. Object[]扩容策略2倍
 * 3. 所有方法被`synchronized`修饰
 */
@Test
public void T3_Vector_SC() {
    // Object[].length = 10
    Vector<String> noArgs = new Vector<>();
    noArgs.add("ooxx");

    // Object[].length = 3
    Vector<String> args = new Vector<>(3);
}

1. SC

class _Vector<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    // 1. 底层数组
    protected Object[] elementData;

    // 容器长度
    protected int elementCount;
    protected int capacityIncrement;

    // 2. 默认数组长度10(饿汉式)
    public _Vector() {
        this(10);
    }

    public _Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

    public _Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);

        // 饿汉式init
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

    // ** synchronized **
    public synchronized boolean add(E e) {
        modCount++;
        // 3. 确认容量
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

    // 3.1. 判断是否扩容
    private void ensureCapacityHelper(int minCapacity) {
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    // 3.2. 扩容。2倍容量
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;

        // Object[]扩容2倍
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);

        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);

        // old[] => new[]
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0)
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }

    @Override
    public E get(int index) {
        return null;
    }

    @Override
    public int size() {
        return 0;
    }
}







 




 



 







 




 


 







 









 







 


















5. Stack

  1. Stack和Vector都被淘汰
  2. class Stack<E> extends Vector<E>
  3. 后进先出(LIFO,last in first out)
image-20220909092156517
/**
 * 1. Stack和Vector都被淘汰
 * 2. `class Stack<E> extends Vector<E>`
 * 3. 后进先出(LIFO,last in first out)
 */
@Test
public void T4_Stack() {
    Stack<String> s = new Stack<>();

    // 返回boolean
    s.add("A");
    s.add("B");
    s.add("C");
    s.add("D");
    System.out.println("s = " + s);

    System.out.println("s.empty() = " + s.empty());
    System.out.println("查看栈顶元素,s.peek() = " + s.peek());
    System.out.println("弹出栈顶元素,s.pop() = " + s.pop());

    // add()功能一样,返回<E>
    s.push("D");
    System.out.println("s = " + s);
}










 





 
 
 


 


1. 应用

  1. 内存分析:形参,局部变量放入栈中(堆:利用完全二叉树结构来维护一组数据)
  2. 网络浏览器“后退”按钮
  3. 文本编辑器撤销功能(ctrl + z:撤销)

6. LinkedList

  1. ArrayList
    1. 物理结构:紧密结构 => 数组
    2. 逻辑结构:线性表
  2. LinkedList
    1. 物理结构:跳转结构 => 双向链表
    2. 逻辑结构:线性表

1. API

  1. List.add(e), Deque.offer(e)区别
    • void, boolean
  2. Deque.poll(), Deque.remove()区别
    • null, NoSuchElementException
public class T3_LinkedList {

    /*
     * 1. 增加
     *      addFirst(E e), addLast(E e)
     *      offer(E e), offerFirst(E e), offerLast(E e)
     * 2. 删除
     *      poll(), pollFirst(), pollLast() => JDK1.6后方法,提高健壮性
     *      removeFirst(), removeLast()
     * 3. 修改
     * 4. 查看
     *      element()
     *      getFirst(), getLast()
     *      indexOf(Object o), lastIndexOf(Object o)
     *      peek(), peekFirst(), peekLast()
     * 5. 判断
     */
    @Test
    public void API() {
        LinkedList<String> list = new LinkedList<>();
        // 1.1. add() => void
        list.add("11");
        list.addFirst("22");
        list.addLast("33");
        System.out.println(list);

        // 1.2. offer() => boolean
        boolean offer = list.offer("44");
        boolean offerFirst = list.offerFirst("55");
        boolean offerLast = list.offerLast("66");
        // 可以添加重复数据
        System.out.println(list);

        // 2.1. poll() => null
        System.out.println("list.poll() = " + list.poll());
        System.out.println("list.pollFirst() = " + list.pollFirst());
        System.out.println("list.pollLast() = " + list.pollLast());
        System.out.println(list);

        // 2.2. remove() => NoSuchElementException
        System.out.println("list.removeFirst() = " + list.removeFirst());
        System.out.println("list.removeLast() = " + list.removeLast());
        System.out.println(list);

        // 2.3. 清空
        list.clear();
        System.out.println(list);


        list.add("iterator");
        // 4.1. 普通for
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        // 4.2. 增强for
        for (String s : list) {
            System.out.println(s);
        }

        // 4.3. 迭代器
        Iterator<String> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }

    @Test
    public void SC() {
        // 无界,无参构造
        LinkedList<Integer> ints = new LinkedList<>();
        ints.add(1);
    }
}





















 





 
 
 




 
 
 



 
 



 





 




 




 












2. SC

  1. JDK1.7、JDK1.8的LinkedList源码一致
  2. 无界,只能无参构造
  3. Node内部类,item, next, prev
  4. get()二分index遍历
class _LinkedList<E> {

    // 1. Node内部类
    private static class Node<E> {
        E item;       // 当前元素
        Node<E> next; // 下一个元素
        Node<E> prev; // 上一个元素

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

    transient Node<E> first; // 首节点
    transient Node<E> last;  // 尾节点
    transient int size = 0;  // 容器长度

    public _LinkedList() {
    }

    // 2.1. 添加操作
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

    // 2.2. 添加算法
    void linkLast(E e) {
        final Node<E> l = last;
        // 维护了prev
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;

        // 第一个节点
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
    }

    // 3. 容器长度
    public int size() {
        return size;
    }

    // 4.1. 索引获取元素
    public E get(int index) {
        // checkElementIndex(index); 健壮性考虑
        return node(index).item;
    }

    // 4.2. 索引遍历算法
    Node<E> node(int index) {
        // index在链表前半段,从前往后找
        if (index < (size >> 1)) {
            Node<E> x = first;
            for (int i = 0; i < index; i++)
                x = x.next;
            return x;
        }
        // index在链表后半段,从后往前找
        else {
            Node<E> x = last;
            for (int i = size - 1; i > index; i--)
                x = x.prev;
            return x;
        }
    }
}























 





 














 




 





 
















7. Set

public class T4_Set {

    @Data
    @ToString
    @AllArgsConstructor
    static class Student implements Comparable<Student> {
        Integer age;
        String name;

        @Override
        public int compareTo(Student o) {
            return this.getAge() - o.getAge();
        }
    }
}










 




/**
 * 1. API和Collection一致
 * 2. 没有index相关的方法
 * 3. 无普通for循环
 */
@Test
public void API() {
    Set<Integer> hsi = new HashSet<>();
    System.out.println("hsi.add(19) = " + hsi.add(19));
    hsi.add(5);
    hsi.add(20);
    System.out.println("hsi.add(19) = " + hsi.add(19));
    hsi.add(41);
    hsi.add(0);
    // 唯一、无序
    System.out.println("hsi.size() = " + hsi.size());
    System.out.println(hsi);

    System.out.println("-----------------------------------------");

    Set<Student> hs = new HashSet<>();
    hs.add(new Student(1, "a"));
    hs.add(new Student(19, "b"));
    hs.add(new Student(20, "d"));
    hs.add(new Student(18, "c"));
    System.out.println("hs.add(new Student(19, w)) = " + hs.add(new Student(19, "w"))); // true 进行覆盖
    hs.add(new Student(10, "t"));
    System.out.println("hs.size() = " + hs.size());
    // Student(id=19, name=lili)出现了2次
    System.out.println(hs);
}

1. HashSet

  1. 特点
    1. 基本类型(唯一、无序)
    2. 自定义引用类型(唯一、无序),需要重写hashCode(), equals()
  2. 底层原理 => HashMap的key,永远无法进行覆盖
    1. 哈希表 = 数组 + 链表
    2. hashCode() + 算法 => 数组位置
    3. equals() => 链表位置
    4. map_value都一样,PRESENT

1. SC

class _HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable {

    private transient HashMap<E, Object> map;
    private static final Object PRESENT = new Object();

    // 1. 底层HashMap
    public _HashSet() {
        map = new HashMap<>();
    }

    // 2. map_value都一样,PRESENT
    public boolean add(E e) {
        return map.put(e, PRESENT) == null;
    }

    @Override
    public Iterator<E> iterator() {
        return null;
    }

    @Override
    public int size() {
        return 0;
    }
}







 




 












2. LinkedHashSet

  1. 唯一、有序(输入顺序)
  2. 底层 LinkedHashMap
  3. LinkedHashMap.Entry继承自HashMap.Node,额外增加了before, after。元素之间维护一条双向链表
/**
 * 1. 唯一、有序(输入顺序)
 * 2. 底层LinkedHashMap
 * 3. `LinkedHashMap.Entry`继承自`HashMap.Node`,额外增加了`before(), after()`。元素之间维护一条双向链表
 */
@Test
public void LinkedHashSet() {
    LinkedHashSet<String> lhs = new LinkedHashSet<>();
    lhs.add("hello");
    lhs.add("apple");
    lhs.add("banana");
    lhs.add("html");
    lhs.add("apple");
    lhs.add("css");
    // 1. 少一个 2. 输入顺序
    System.out.println("lhs.size() = " + lhs.size());
    System.out.println(lhs);
}

1. SC

public class LinkedHashSet<E> extends HashSet<E> implements Set<E>, Cloneable, Serializable {

    public LinkedHashSet() {
        super(16, .75f, true);
    }
}



 


public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable {

    private transient HashMap<E,Object> map;
    private static final Object PRESENT = new Object();

    public HashSet() {
        map = new HashMap<>();
    }

    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

}










 



public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {

    static class Entry<K,V> extends HashMap.Node<K,V> {
        Entry<K,V> before, after;

        Entry(int hash, K key, V value, Node<K,V> next) {
            super(hash, key, value, next);
        }
    }

}



 







3. TreeSet

  1. 唯一, 有序(升序遍历)
  2. 底层TreeMap的key(二叉树,中序遍历),永远无法覆盖
  3. 比较需要Comparator
/**
 * 1. 唯一, 有序(升序遍历)
 * 2. 底层TreeMap(二叉树,中序遍历)
 * 3. 比较需要Comparator
 */
@Test
public void TreeSet() {
    TreeSet<Integer> ts_int = new TreeSet<>();
    ts_int.add(12);
    ts_int.add(3);
    ts_int.add(7);
    ts_int.add(9);
    ts_int.add(3);
    ts_int.add(16);
    // 1. 少一个 2. 升序
    System.out.println("ts_int.size() = " + ts_int.size());
    System.out.println(ts_int);

    System.out.println("-----------------------------------------");

    TreeSet<String> ts_str = new TreeSet<>();
    ts_str.add("e");
    ts_str.add("b");
    ts_str.add("a");
    ts_str.add("d");
    ts_str.add("c");
    ts_str.add("d");
    // 1. 少一个 2. 字母顺序
    System.out.println("ts_str.size() = " + ts_str.size());
    System.out.println(ts_str);

    System.out.println("-----------------------------------------");

    // 内部比较器
    TreeSet<Student> ts_stu = new TreeSet<>();
    ts_stu.add(new Student(10, "e"));
    ts_stu.add(new Student(8, "b"));
    ts_stu.add(new Student(4, "a"));
    ts_stu.add(new Student(9, "e"));
    System.out.println("ts_stu.add(new Student(8, f)) = " + ts_stu.add(new Student(8, "f"))); // false 加不进去
    ts_stu.add(new Student(1, "d"));
    System.out.println("ts_stu.size() = " + ts_stu.size());
    System.out.println(ts_stu);

    System.out.println("-----------------------------------------");

    // 外部比较器
    Comparator<Student> com_stu = Comparator.comparingInt(Student::getAge).reversed();
    TreeSet<Student> ts_outer = new TreeSet<>(com_stu);
    ts_outer.add(new Student(10, "e"));
    ts_outer.add(new Student(8, "b"));
    ts_outer.add(new Student(4, "a"));
    ts_outer.add(new Student(9, "e"));
    System.out.println("ts_outer.add(new Student(8, f)) = " + ts_outer.add(new Student(8, "f")));
    ts_outer.add(new Student(1, "d"));
    System.out.println("ts_outer.size() = " + ts_outer.size());
    System.out.println(ts_outer);
}














 












 











 







 
 









1. SC

class _TreeSet<E>
        // extends AbstractSet<E> implements NavigableSet<E>, Cloneable, Serializable
{
    // TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>
    private transient NavigableMap<E, Object> m;
    private static final Object PRESENT = new Object();

    // 1. 底层TreeMap
    public _TreeSet() {
        this(new TreeMap<E, Object>());
    }

    _TreeSet(NavigableMap<E, Object> m) {
        this.m = m;
    }

    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

    // 2. map_value都一样,PRESENT
    public boolean add(E e) {
        return m.put(e, PRESENT) == null;
    }
}









 







 




 


8. Collections

1. API

/**
 * Collections构造器私有化,方法都static
 */
public class T5_Collections {

    /**
     * 1. addAll():添加
     * 2. sort():排序 => 升序
     * 3. binarySearch():二分查询 => 集合有序
     * 4. copy():替换方法
     * 5. fill():填充
     */
    @Test
    public void API() {
        ArrayList<String> list = new ArrayList<>();
        list.add("aa");
        list.add("cc");
        list.add("bb");
        // 1. addAll():添加
        Collections.addAll(list, "dd", "ee", "ff");

        System.out.println("addAll() = " + list);

        // 2. sort():排序 => 升序
        Collections.sort(list);
        System.out.println("sort() = " + list);

        // 3. binarySearch():二分查询 => 集合有序
        System.out.println("binarySearch() = " + Collections.binarySearch(list, "cc"));

        // 4. copy():替换方法
        ArrayList<String> list2 = new ArrayList<>();
        Collections.addAll(list2, "xx", "yy");
        Collections.copy(list, list2); // 将list2元素覆盖到list

        System.out.println("list2_copy() = " + list2);
        System.out.println("list_copy() = " + list);

        // 5. fill():填充
        Collections.fill(list2, "zzz");
        System.out.println("fill() = " + list2);
    }
}



















 




 



 




 





 



addAll() = [aa, cc, bb, dd, ee, ff]
sort() = [aa, bb, cc, dd, ee, ff]
binarySearch() = 2
list2_copy() = [xx, yy]
list_copy() = [xx, yy, cc, dd, ee, ff]
fill() = [zzz, zzz]

2. sync

List<String> list;
// ArrayList、HashMap,线程不安全
@Test
public void thread_unsafe() {
    list = new ArrayList<>();
    ooxx();
}

// to线程安全
@Test
public void toSync_SC() {
    list = Collections.synchronizedList(new ArrayList<>());
    ooxx();
}

private void ooxx() {
    ExecutorService es = Executors.newFixedThreadPool(100);
    for (int i = 0; i < 10_000; i++) {
        es.execute(() -> list.add("aaa"));
    }

    es.shutdown();
    // 监控
    while (true) {
        if (es.isTerminated()) {
            System.out.println("list.size() = " + list.size());
            break;
        }
    }
}











 


















class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable
public class Collections {

  	// 1. async() => sync() 泛型方法
    public static <T> List<T> synchronizedList(List<T> list) {
        return (list instanceof RandomAccess ?
                // 2.1.
                new SynchronizedRandomAccessList<>(list) :
                new SynchronizedList<>(list));
    }

    // 2.2.
    static class SynchronizedRandomAccessList<E> extends SynchronizedList<E> implements RandomAccess {

        // 3.1.
        SynchronizedRandomAccessList(List<E> list) {
            super(list);
        }
    }

    // 3.2.
    static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> {

        final List<E> list;

        SynchronizedList(List<E> list) {
            // 4.1.
            super(list);
            this.list = list;
        }
    }

    static class SynchronizedCollection<E> implements Collection<E>, Serializable {

        final Collection<E> c;  // Backing Collection
        final Object mutex;     // Object on which to synchronize

        // 4.2.
        SynchronizedCollection(Collection<E> c) {
            this.c = c;
            mutex = this;
        }

      	// 5. **加锁**
        public boolean add(E e) {
            synchronized (mutex) {
               return c.add(e);
            }
        }

      	// ...
    }
}