JDK8源码阅读(十一) CopyOnWriteArrayList TODO

一、简介

 

二、分析

 

2.1 类结构

 

2.1.0 类结构图

 

2.2 内部类

 

2.2.0 内部类列表图

2.2.1 COWIterator

    /**
     * 静态内部类迭代器COWIterator
     */
    static final class COWIterator<E> implements ListIterator<E> {
        // 内部数组快照
        private final Object[] snapshot;
        // 迭代器开始遍历的索引  遍历的是子数组
        private int cursor;

        // 构造函数,指定数组和开始遍历索引位置
        private COWIterator(Object[] elements, int initialCursor) {
            cursor = initialCursor;
            snapshot = elements;
        }

        // 判断是否有后继元素
        public boolean hasNext() {
            // 索引是否小于快照的长度
            return cursor < snapshot.length;
        }

        // 是否有前驱元素
        public boolean hasPrevious() {
            // 光标大于0 则有 否则没有
            return cursor > 0;
        }

        // 获取下个元素
        @SuppressWarnings("unchecked")
        public E next() {
            // 检验是否还有下个元素
            if (! hasNext())
                throw new NoSuchElementException();
            // 返回下个元素,并将光标自增
            return (E) snapshot[cursor++];
        }

        // 获取前驱元素
        @SuppressWarnings("unchecked")
        public E previous() {
            // 校验是否有前驱元素
            if (! hasPrevious())
                throw new NoSuchElementException();
            // 返回前驱元素,并将光标索引递减
            return (E) snapshot[--cursor];
        }

        // 获取下个元素的索引位置 也就是当前光标
        public int nextIndex() {
            return cursor;
        }

        // 获取上一个元素的索引位置
        public int previousIndex() {
            // 当前光标减1
            return cursor-1;
        }

        /**
         * 过时方法,不再支持
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }

        /**
         * 过时方法,不再支持
         */
        public void set(E e) {
            throw new UnsupportedOperationException();
        }

        /**
         * 过时方法,不再支持
         */
        public void add(E e) {
            throw new UnsupportedOperationException();
        }

        
        /**
         * 提供JDK8的lambda方式遍历 TODO
         */    
        @Override
        public void forEachRemaining(Consumer<? super E> action) {
            // 检验非空
            Objects.requireNonNull(action);
            // 备份数组并获取长度
            Object[] elements = snapshot;
            final int size = elements.length;
            // TODO
            for (int i = cursor; i < size; i++) {
                @SuppressWarnings("unchecked") E e = (E) elements[i];
                action.accept(e);
            }
            cursor = size;
        }
    }

2.2.2 COWSubList

2.2.3 COWSubListIterator

 

2.3 字段

2.3.0 字段列表图

 

2.3.1 array

  • /**
     * 内部维护的数组集合,只能通过getArray或setArray来访问
     */
    private transient volatile Object[] array;

     

2.3.2 lock 

  • /**
     * 内部采用独占锁ReetrantLock来保证并发操作
     */
    final transient ReentrantLock lock = new ReentrantLock();

 

2.3.3 lockOffset

/**
 * lock锁的在该类中的偏移量,方便Unsafe类进行cas操作
 */
private static final long lockOffset;

 

2.2.4 UNSAFE

/**
 * 用来进行CAS操作的类
 */
private static final sun.misc.Unsafe UNSAFE;

 

2.4 代码块

2.4.1 静态代码块

    /**
     * 使用Unsafe的方法获取到lock字段的偏移量用于cas操作
     */
    static {
        try {
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            Class<?> k = CopyOnWriteArrayList.class;
            lockOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("lock"));
        } catch (Exception e) {
            throw new Error(e);
        }
    }

 

 

2.5 方法

2.5.0 方法列表图

 

2.5.1 构造函数

    /**
     * 无参构造函数,默认调用setArray方法将内部维护的数组初始化一个长度为0的数组集合
     */
    public CopyOnWriteArrayList() {
        setArray(new Object[0]);
    }

    
    /**
     * 接收一个Collection类型的集合的构造函数。
     * 如果该类是CopyOnWriteArrayList,则直接调用getArray方法拿到数组并通过setArray方法设置到内部维护的数据中
     * 如果不是,则直接调用toArray()方法拿到数组,然后设置。如果toArray()方法返回的不是数组,则再调用Arrays工具类的copyOf方法进行复制
     */
    public CopyOnWriteArrayList(Collection<? extends E> c) {
        Object[] elements;
        if (c.getClass() == CopyOnWriteArrayList.class)
            elements = ((CopyOnWriteArrayList<?>)c).getArray();
        else {
            elements = c.toArray();
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elements.getClass() != Object[].class)
                elements = Arrays.copyOf(elements, elements.length, Object[].class);
        }
        setArray(elements);
    }


    /**
     * 接收一个数组的构造参数,内部调用Arrays类个copyOf方法进行拷贝数组
     */
    public CopyOnWriteArrayList(E[] toCopyIn) {
        setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
    }

    
    

 

2.5.2 getArray()

    /**
     * 获取内部维护的数组
     */
    final Object[] getArray() {
        return array;
    }

2.5.3 setArray(Object[] a)

    /**
     * 设置内部维护的数组
     */
    final void setArray(Object[] a) {
        array = a;
    }

 

2.5.4 size()

    /**
     * 返回当前维护的数组的长度
     */
    public int size() {
        return getArray().length;
    }

 

2.5.5 isEmpty()

    /**
     * 判断该当前维护的数组的长度是否为0
     */
    public boolean isEmpty() {
        return size() == 0;
    }

 

2.5.6 eq(Object o1, Object o2)

    /**
     * 比较俩个对象是否相等,包含null
     */
    private static boolean eq(Object o1, Object o2) {
        return (o1 == null) ? o2 == null : o1.equals(o2);
    }

 

2.5.7 indexOf(Object o, Object[] elements, int index, int fence)

    /**
     * 查询元素在指定数组中在index索引到fence索引之间是否存在,如果存在,则返回索引,不存在,返回-1
     * 元素可以为null
     */
    private static int indexOf(Object o, Object[] elements,
                               int index, int fence) {
        if (o == null) {
            for (int i = index; i < fence; i++)
                if (elements[i] == null)
                    return i;
        } else {
            for (int i = index; i < fence; i++)
                if (o.equals(elements[i]))
                    return i;
        }
        return -1;
    }

 

2.5.8 lastIndexOf(Object o, Object[] elements, int index)

    /**
     * 判断对象O在数据elements上index索引前最后一次出现的位置,如果有,则返回索引,否则返回-1
     */ 
    private static int lastIndexOf(Object o, Object[] elements, int index) {
        if (o == null) {
            for (int i = index; i >= 0; i--)
                if (elements[i] == null)
                    return i;
        } else {
            for (int i = index; i >= 0; i--)
                if (o.equals(elements[i]))
                    return i;
        }
        return -1;
    }

 

2.5.9 contains(Object o)

    /**
     * 判断当前数组是否包含元素O 
     */
    public boolean contains(Object o) {
        Object[] elements = getArray();
        return indexOf(o, elements, 0, elements.length) >= 0;
    }

 

2.5.10 indexOf(Object o)

    /**
     * 查询对象O在当前数组中的索引,如果有返回索引,没有返回-1
     */
    public int indexOf(Object o) {
        Object[] elements = getArray();
        return indexOf(o, elements, 0, elements.length);
    }

 

2.5.11 indexOf(E e, int index)

    /**
     * 查询元素E在当前数组中从索引index处开始首次出现的位置, 如果有,返回索引,没有,返回-1
     */
    public int indexOf(E e, int index) {
        Object[] elements = getArray();
        return indexOf(e, elements, index, elements.length);
    }

 

2.5.12 lastIndexOf(Object o)

    /**
     * 查询对象O在当前数组中最后出现的位置索引,有返回,没有返回-1
     */ 
    public int lastIndexOf(Object o) {
        Object[] elements = getArray();
        return lastIndexOf(o, elements, elements.length - 1);
    }

 

2.5.13 lastIndexOf(E e, int index)

    /**
     * 获取元素e在当前数组中指定index索引之前最后出现的位置索引,如果有,返回,否则返回-1
     */
    public int lastIndexOf(E e, int index) {
        Object[] elements = getArray();
        return lastIndexOf(e, elements, index);
    }

 

2.5.14 clone()

    /**
     * 调用Object的clone()方法进行浅拷贝, 内部元素并没有拷贝
     * 然后调用resetLock()方法在指定的lock偏移量位置重新new了一个ReentrantLock对象,重置锁
     */
    public Object clone() {
        try {
            @SuppressWarnings("unchecked")
            CopyOnWriteArrayList<E> clone = (CopyOnWriteArrayList<E>) super.clone();
            clone.resetLock();
            return clone;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError();
        }
    }

 

2.5.15 resetLock()

    /**
     * 重置ReentrantLock锁
     */
    private void resetLock() {
        UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
    }

 

2.5.16 toArray()

    /**
     * 返回一个数组,内部调用Arrays工具类的copuOff方法
     */
    public Object[] toArray() {
        Object[] elements = getArray();
        return Arrays.copyOf(elements, elements.length);
    }

 

2.5.17  toArray(T a[])

    /**
     * 如果目标数组的长度小于内部维护数组的长度,则直接调用Arrays的copyOf方法拷贝;
     * 否则: 先调用System.arraycopy方法进行拷贝,如果目标数组的长度大于内部维护数组的长度,则将目标数组置空 
     * ??? 为啥如果长达大了不直接置空
     */
    public <T> T[] toArray(T a[]) {
        Object[] elements = getArray();
        int len = elements.length;
        if (a.length < len)
            return (T[]) Arrays.copyOf(elements, len, a.getClass());
        else {
            System.arraycopy(elements, 0, a, 0, len);
            if (a.length > len)
                a[len] = null;
            return a;
        }
    }

 

2.5.18 get(Object[] a, int index)

    /**
     * 获取数组中指定索引的元素对象
     */
    private E get(Object[] a, int index) {
        return (E) a[index];
    }

 

2.5.19 get(int index)

    /**
     * 获取内部维护的数组指定索引的元素
     */
    public E get(int index) {
        return get(getArray(), index);
    }

 

2.5.20 set(int index, E element)

    /**
     * 修改内部维护数组指定索引处的对象为新对象,并返回旧对象
     */
    public E set(int index, E element) {
        // 获取内部的独占锁ReentrantLock 
        final ReentrantLock lock = this.lock;
        // 加锁
        lock.lock();

        try {
            // 拿到内部的数组,并获取到指定索引的旧对象
            Object[] elements = getArray();
            E oldValue = get(elements, index);

            // 如果不一样,则使用Arrays类的copyOf方法拿到新数组,然后替换,并更新重新放回即可
            if (oldValue != element) {
                int len = elements.length;
                Object[] newElements = Arrays.copyOf(elements, len);
                newElements[index] = element;
                setArray(newElements);
            } else {
                // 如果一样,则直接放回即可        
                // Not quite a no-op; ensures volatile write semantics
                setArray(elements);
            }
            // 返回旧对象
            return oldValue;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

 

2.5.21 add(E e)

    /**
     * 添加元素
     */
    public boolean add(E e) {
        // 获取到独占锁ReentrantLock 并加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 获取到内部的数组和长度
            Object[] elements = getArray();
            int len = elements.length;
            // 使用Arrays的copyOf方法将原数组拷贝到新数组,长度加一
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            // 将新加的索引位置的元素置为新加的元素 
            newElements[len] = e;
            // 放回数组
            setArray(newElements);
            return true;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

 

2.5.22 add(int index, E element)

    /**
     * 在指定索引出添加元素
     */   
    public void add(int index, E element) {
        // 获取独占锁ReentranntLock,并加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 获取到内部的数组和长度
            Object[] elements = getArray();
            int len = elements.length;
            // 校验索引
            if (index > len || index < 0)
                throw new IndexOutOfBoundsException("Index: "+index+
                                                    ", Size: "+len);
            Object[] newElements;
            // 需要移动的元素个数
            int numMoved = len - index;
            // 如果是在最后位置添加元素,则调用Arrays的copyOf方法将数组复制,并长度加一
            if (numMoved == 0)
                newElements = Arrays.copyOf(elements, len + 1);
            else {
                // 否则,将新数组长度置为旧数组长度加1
                newElements = new Object[len + 1];
                // 调用System的arraycopy方法将添加位置之前的元素拷贝到新数组
                System.arraycopy(elements, 0, newElements, 0, index);
                // 调用System的arraycopy方法将添加位置之后的元素拷贝到新数组
                System.arraycopy(elements, index, newElements, index + 1,
                                 numMoved);
            }
            // 更新指定索引位置的元素
            newElements[index] = element;
            // 放回内部维护的数组
            setArray(newElements);
        } finally {
            // 解锁
            lock.unlock();
        }
    }

 

2.5.23 remove(int index)

    /**
     * 删除指定索引处的元素
     */
    public E remove(int index) {
        // 获取独占锁并加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 获取内部维护的数组和其长度
            Object[] elements = getArray();
            int len = elements.length;
            // 获取指定索引位置的旧元素
            E oldValue = get(elements, index);
            // 获取需要移动的元素的个数 
            int numMoved = len - index - 1;
            // 如果不需要移动,即删除的是最后一个元素
            if (numMoved == 0)
                // 调用Arrays的copyOf方法将旧数组拷贝到新数组,最后一个不拷贝,然后写回内部维护的数组
                setArray(Arrays.copyOf(elements, len - 1));
            else {
                // 如果删除的不是最后一个元素,则创建新数组,长度为旧数组长度减1
                Object[] newElements = new Object[len - 1];
                // 将删除元素前面的元素调用System.arraycopy方法拷贝到新数组
                System.arraycopy(elements, 0, newElements, 0, index);
                // 将删除元素后面的元素调用System.arraycopy方法拷贝到新数组
                System.arraycopy(elements, index + 1, newElements, index,
                                 numMoved);
                // 写回内部维护的数组
                setArray(newElements);
            }
            return oldValue;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

 

2.5.24 remove(Object o)

    /**
     * 删除元素
     */
    public boolean remove(Object o) {
        // 获取内部维护数组的快照
        Object[] snapshot = getArray();
        // 获取元素O在快照中的索引位置
        int index = indexOf(o, snapshot, 0, snapshot.length);
        // 如果不存在,则返回false,存在,则调用下面的remove方法进行删除
        return (index < 0) ? false : remove(o, snapshot, index);
    }

 

2.5.25 remove(Object o, Object[] snapshot, int index)

    /**
     * 将数组snapshot中指定index索引的数据或者指定对象O删除
     * 如果传递的数组和当前维护的数组相同,则删除指定索引的元素,否则删除内部维护数组的对象O
     * 注意:如果后者
     */
    private boolean remove(Object o, Object[] snapshot, int index) {
        // 使用独占锁ReentrantLock加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份当前数组
            Object[] current = getArray();
            // 记录当前数组长度
            int len = current.length;

            // 如果传递的数组和内部维护的数组不同,则根据对象O查询索引进行删除
            if (snapshot != current) findIndex: {
                // 获取俩个数组的长度最小值 
                int prefix = Math.min(index, len);
                // 遍历获取对象O在内部维护数组的索引
                for (int i = 0; i < prefix; i++) {
                    if (current[i] != snapshot[i] && eq(o, current[i])) {
                        index = i;
                        break findIndex;
                    }
                }
                // 索引校验
                if (index >= len)
                    return false;
                if (current[index] == o)
                    break findIndex;
                index = indexOf(o, current, index, len);
                if (index < 0)
                    return false;
            }

            // 创建一个新数组,长度比原数组长度少1
            Object[] newElements = new Object[len - 1];
            // 调用System.arraycopy方法进行分俩次将备份数组拷贝到新创建的数组中
            System.arraycopy(current, 0, newElements, 0, index);
            System.arraycopy(current, index + 1, newElements, index, len - index - 1);

            // 写回内部数组
            setArray(newElements);

            return true;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.26 removeRange(int fromIndex, int toIndex)

    /**
     * 删除索引在formIndex和toIndex之间的数组元素
     */
    void removeRange(int fromIndex, int toIndex) {
        // 加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份数组并记录长度
            Object[] elements = getArray();
            int len = elements.length;
            
            // 参数校验
            if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
                throw new IndexOutOfBoundsException();

            // 获取新的数组长度
            int newlen = len - (toIndex - fromIndex);

            // 删除的元素个数
            int numMoved = len - toIndex;

            // 如果俩个索引相同,则调用Arrays.copyOf方法将备份数组写回即可
            if (numMoved == 0)
                setArray(Arrays.copyOf(elements, newlen));
            else {
                // 创建新数组
                Object[] newElements = new Object[newlen];
                // 调用System类的arraycopy方法分俩次将数组拷贝到新数组中
                System.arraycopy(elements, 0, newElements, 0, fromIndex);
                System.arraycopy(elements, toIndex, newElements,                          fromIndex, numMoved);
                // 写回内部数组
                setArray(newElements);
            }
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.27 addIfAbsent(E e)

    /**
     * 如果当前元素在数组中不存在,则调用addIfAbsent方法进行删除,否则返回false
     */
    public boolean addIfAbsent(E e) {
        // 备份数组快照
        Object[] snapshot = getArray();
        // 如果存在,则返回false,否则删除
        return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
            addIfAbsent(e, snapshot);
    }

2.2.28 addIfAbsent(E e, Object[] snapshot)

    /**
     * 如果元素在快照中不存在,则添加,否则,返回false
     */
    private boolean addIfAbsent(E e, Object[] snapshot) {
        // 加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份数组,获取长度
            Object[] current = getArray();
            int len = current.length;

            // 如果传递的数组和内部数组快照不同
            if (snapshot != current) {
                // Optimize for lost race to another addXXX operation
                // 获取传递数组和内部维护数组的长度最小值,方便快速判断
                int common = Math.min(snapshot.length, len);
                // 遍历,快照中如果元素在0~common索引之间存在则返回false
                for (int i = 0; i < common; i++)
                    if (current[i] != snapshot[i] && eq(e, current[i]))
                        return false;
                // 如果快照中元素在common,len之间存在,也返回false
                if (indexOf(e, current, common, len) >= 0)
                        return false;
            }

            // 创建新长度的数组,长度比之前大1,并将新增元素添加
            Object[] newElements = Arrays.copyOf(current, len + 1);
            newElements[len] = e;

            // 写回内部维护数组
            setArray(newElements);
            return true;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.29 containsAll(Collection<?> c)

    /**
     * 判断内部维护的数组是否包含传入集合的所有元素
     */
    public boolean containsAll(Collection<?> c) {
        // 备份数组并记录长度
        Object[] elements = getArray();
        int len = elements.length;
        // 遍历传递过来的集合中的元素,查看是否在快照中存在,有一个不存在就返回false
        for (Object e : c) {
            if (indexOf(e, elements, 0, len) < 0)
                return false;
        }
        // 如果元素都存在则返回true
        return true;
    }

2.2.30 removeAll(Collection<?> c)

    /**
     * 删除内部数组中在传递数组中的所有元素
     */ 
    public boolean removeAll(Collection<?> c) {
        // 参数校验
        if (c == null) throw new NullPointerException();
        // 加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份数组快照并记录长度
            Object[] elements = getArray();
            int len = elements.length;
  
            if (len != 0) {
                // temp array holds those elements we know we want to keep
                int newlen = 0;
                // 创建临时数组,长度为快照的长度
                Object[] temp = new Object[len];
                // 遍历快照,如果元素在目标数组中不存在,则将元素放到新数组中
                for (int i = 0; i < len; ++i) {
                    Object element = elements[i];
                    if (!c.contains(element))
                        temp[newlen++] = element;
                }
                // 重置新数组的长度,并写回到内部维护的数组
                if (newlen != len) {
                    setArray(Arrays.copyOf(temp, newlen));
                    return true;
                }
            }
            return false;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.31 retainAll(Collection<?> c)

    /**
     * 获取内部数组和目标数组的交集,并写回到内部数组
     */
    public boolean retainAll(Collection<?> c) {
        // 空指针校验
        if (c == null) throw new NullPointerException();
        // 加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份数组和获取长度
            Object[] elements = getArray();
            int len = elements.length;
            
            if (len != 0) {
                // 创建一个新数组用来保存希望保留的元素
                int newlen = 0;
                Object[] temp = new Object[len];
                // 遍历备份数组,如果元素同时在备份数组和目标数组中存在,则存储到新数组中
                for (int i = 0; i < len; ++i) {
                    Object element = elements[i];
                    if (c.contains(element))
                        temp[newlen++] = element;
                }
                // 如果俩个长度不相等,则将新数组写回  如果俩个数组相同,则不需要写回
                if (newlen != len) {
                    setArray(Arrays.copyOf(temp, newlen));
                    return true;
                }
            }
            return false;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.32 addAllAbsent(Collection<? extends E> c) 

    /**
     * 将目标集合中不存在的元素添加的内部维护的数组中 取并集
     */
    public int addAllAbsent(Collection<? extends E> c) {
        // 将目标集合转换为数组并校验长度
        Object[] cs = c.toArray();
        if (cs.length == 0)
            return 0;

        // 加独占锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份内部数组并获取长度
            Object[] elements = getArray();
            int len = elements.length;
            int added = 0;
        
            // uniquify and compact elements in cs
            // 遍历目标数组
            for (int i = 0; i < cs.length; ++i) {
                Object e = cs[i];
                // 如果目标数组中的对象在备份的内部数组中不存在并且在目标数组之前没有出现过
                if (indexOf(e, elements, 0, len) < 0 &&
                    indexOf(e, cs, 0, added) < 0)
                    cs[added++] = e;
            }
            // added大于0说明存在并集元素
            if (added > 0) {
                // 创建新数组,将原备份数组拷贝进去,并将长度修改为并集的长度
                Object[] newElements = Arrays.copyOf(elements, len + added);
                // 将目标数组从0角标开始拷贝added个元素到新数组的len角标后面
                System.arraycopy(cs, 0, newElements, len, added);
                // 写回
                setArray(newElements);
            }
            // 返回添加的元素个数
            return added;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.33 clear()

    /**
     * 清空数组
     */
    public void clear() {
        // 加独占锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 将一个长度为0的数组写回
            setArray(new Object[0]);
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.34 addAll(Collection<? extends E> c)

    /**
     * 将目标集合添加到当前集合中
     */
    public boolean addAll(Collection<? extends E> c) {

        // 获取参数集合的内部数组
        Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
            ((CopyOnWriteArrayList<?>)c).getArray() : c.toArray();
        // 长度校验
        if (cs.length == 0)
            return false;

        // 加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份内部数组、获取长度
            Object[] elements = getArray();
            int len = elements.length;
            // 如果此时内部备份数组长度为0,则将参数数组写回到内部维护的数组中
            if (len == 0 && cs.getClass() == Object[].class)
                setArray(cs);
            else {
                // 创建一个新数组,元素为备份数组,长度为俩者之和
                Object[] newElements = Arrays.copyOf(elements, len + cs.length);
                // 将目标数组拷贝到新数组中
                System.arraycopy(cs, 0, newElements, len, cs.length);
                // 写回内部维护的数组
                setArray(newElements);
            }
            return true;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.35 addAll(int index, Collection<? extends E> c)

    /**
     * 将目标数组插入到新数组中 
     */
    public boolean addAll(int index, Collection<? extends E> c) {

        // 将目标参数转换为数组
        Object[] cs = c.toArray();

        // 加独占锁
        final ReentrantLock lock = this.lock;
        lock.lock();

        try {
            // 备份内部维护数组并获取长度
            Object[] elements = getArray();
            int len = elements.length;
 
            // 校验参数
            if (index > len || index < 0)
                throw new IndexOutOfBoundsException("Index: "+index+ ", Size: "+len);
            if (cs.length == 0)
                return false;

            // 根据开始添加元素的索引计算需要移动元素个数
            int numMoved = len - index;
            
            // 创建新数组
            Object[] newElements;

            // 如果是数组末尾,则只是备份旧数组到新数组中,扩展长度
            if (numMoved == 0)
                newElements = Arrays.copyOf(elements, len + cs.length);
            else {
                // 创建新数组,创建新长度
                newElements = new Object[len + cs.length];

                // 将旧数组中index索引之前的元素拷贝到新数组中
                System.arraycopy(elements, 0, newElements, 0, index);
                // 将旧数组中index索引之后的元素拷贝到新数组中插入新元素集合之后的角标之后
                System.arraycopy(elements, index, newElements, index + cs.length, numMoved);
            }
            // 将目标数组插入到新数组中
            System.arraycopy(cs, 0, newElements, index, cs.length);

            // 写回内部数组
            setArray(newElements);
            return true;
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.36 forEach(Consumer<? super E> action)

    /**
     * jdk8的lambda方式forEach遍历
     */ 
    public void forEach(Consumer<? super E> action) {
        // 校验参数
        if (action == null) throw new NullPointerException();

        // 备份数组并获取长度
        Object[] elements = getArray();
        int len = elements.length;

        // 调用1.8的函数式接口获取元素
        for (int i = 0; i < len; ++i) {
            @SuppressWarnings("unchecked") E e = (E) elements[i];
            action.accept(e);
        }
    }

2.2.37 removeIf(Predicate<? super E> filter)    TODO jdk8

    /**
     *
     */
    public boolean removeIf(Predicate<? super E> filter) {
        // 参数校验
        if (filter == null) throw new NullPointerException();

        // 加独占锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份数组并获取长度
            Object[] elements = getArray();
            int len = elements.length;

            if (len != 0) {
                int newlen = 0;
                Object[] temp = new Object[len];
                for (int i = 0; i < len; ++i) {
                    @SuppressWarnings("unchecked") E e = (E) elements[i];
                    if (!filter.test(e))
                        temp[newlen++] = e;
                }
                if (newlen != len) {
                    setArray(Arrays.copyOf(temp, newlen));
                    return true;
                }
            }
            return false;
        } finally {
            lock.unlock();
        }
    }

2.2.38 replaceAll(UnaryOperator<E> operator) TODO jdk8

    public void replaceAll(UnaryOperator<E> operator) {
        if (operator == null) throw new NullPointerException();
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            Object[] newElements = Arrays.copyOf(elements, len);
            for (int i = 0; i < len; ++i) {
                @SuppressWarnings("unchecked") E e = (E) elements[i];
                newElements[i] = operator.apply(e);
            }
            setArray(newElements);
        } finally {
            lock.unlock();
        }
    }

2.2.39 sort(Comparator<? super E> c)

    /**
     * 使用指定的排序器进行排序
     */
    public void sort(Comparator<? super E> c) {
        // 加独占锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份数组
            Object[] elements = getArray();
            // 创建新数组,元素和备份数组一样 
            Object[] newElements = Arrays.copyOf(elements, elements.length);
            // 调用Arrays的sort方法进行排序
            @SuppressWarnings("unchecked") E[] es = (E[])newElements;
            Arrays.sort(es, c);
            // 写回
            setArray(newElements);
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.40 writeObject(java.io.ObjectOutputStream s)

    /**
     * 将数组写入到指定的输出流中
     */
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {

        // 写数组对象数据
        s.defaultWriteObject();
        
        // 备份数组,并将数组的长度写到流中
        Object[] elements = getArray();
        s.writeInt(elements.length);

        // 将数组元素以合适的顺序写到输出流中
        for (Object element : elements)
            s.writeObject(element);
    }

2.2.41 readObject(java.io.ObjectInputStream s)

    /**
     * 从输入流中获取数组并写回
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {

        // 读对象
        s.defaultReadObject();

        // 获取新的独占锁
        resetLock();

        // 从流中获取对象数组的长度
        int len = s.readInt();
        // 校验长度
        SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, len);
        // 创建新数组
        Object[] elements = new Object[len];

        // 从流中获取对象数组内部的元素
        for (int i = 0; i < len; i++)
            elements[i] = s.readObject();

        // 写回
        setArray(elements);
    }

2.2.42 toString()

    /**
     * 重写toString方法,内部调用Arrays的toString方法
     */
    public String toString() {
        return Arrays.toString(getArray());
    }

    /**
     * Arrays的toString(Arr[])方法,内部采用StringBuilder方法进行拼接
     */
    public static String toString(Object[] a) {
        if (a == null)
            return "null";

        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(String.valueOf(a[i]));
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

2.2.43 equals(Object o)

    /**
     * 重写equals方法
     */
    public boolean equals(Object o) {
        // 如果地址相等,则返回true
        if (o == this)
            return true;
        // 如果对象不是List类型,则返回false
        if (!(o instanceof List))
            return false;
        
        // 强转为List类型并获取迭代器
        List<?> list = (List<?>)(o);
        Iterator<?> it = list.iterator();

        // 备份内部维护数组并获取长度
        Object[] elements = getArray();
        int len = elements.length;

        // 遍历目标数组,遍历长度为备份数组的长度
        for (int i = 0; i < len; ++i)
            // 如果二者元素不同则返回false
            if (!it.hasNext() || !eq(elements[i], it.next()))
                return false;
        // 如果目标数组比备份数组长度长,则返回false
        if (it.hasNext())
            return false;
        return true;
    }

2.2.44 hashCode()

    /**
     * 重写hashCode方法
     */
    public int hashCode() {
        // 初始哈希值为1
        int hashCode = 1;
        // 备份数组并获取长度
        Object[] elements = getArray();
        int len = elements.length;
        // 遍历元素,根据每一个元素计算一次哈希值
        for (int i = 0; i < len; ++i) {
            Object obj = elements[i];
            // 重新计算哈希值
            hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
        }
        // 返回新的哈希值
        return hashCode;
    }

2.2.45 iterator() 

    /**
     * 获取迭代器,返回内部自定义类COWIterator的迭代器
     */
    public Iterator<E> iterator() {
        return new COWIterator<E>(getArray(), 0);
    }

2.2.46 listIterator()

    /**
     * 获取迭代器,返回内部自定义类COWIterator的迭代器
     */
    public ListIterator<E> listIterator() {
        return new COWIterator<E>(getArray(), 0);
    }

2.2.47 listIterator(int index)

    /**
     * 获取迭代器,返回内部自定义的COWIterator迭代器,迭代的集合从index索引开始
     */
    public ListIterator<E> listIterator(int index) {
        // 备份数组并获取长度
        Object[] elements = getArray();
        int len = elements.length;
        // 校验参数
        if (index < 0 || index > len)
            throw new IndexOutOfBoundsException("Index: "+index);
        // 返回自定义的迭代器
        return new COWIterator<E>(elements, index);
    }

2.2.48 spliterator() TODO jdk8

    /**
     *
     */
    public Spliterator<E> spliterator() {
        return Spliterators.spliterator
            (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
    }

2.2.49 subList(int fromIndex, int toIndex)

    /**
     * 返回一个子集合
     */
    public List<E> subList(int fromIndex, int toIndex) {
        // 获取独占锁并加锁
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            // 备份数组并获取长度
            Object[] elements = getArray();
            int len = elements.length;
            // 教研参数
            if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
                throw new IndexOutOfBoundsException();
            // 使用内部类COWSubList创建一个子集合
            return new COWSubList<E>(this, fromIndex, toIndex);
        } finally {
            // 解锁
            lock.unlock();
        }
    }

2.2.50 resetLock()

    /**
     * 重置锁
     */
    private void resetLock() {
        // 使用UNSAFE将lock变量偏移量的位置重置为新的独占锁
        UNSAFE.putObjectVolatile(this, lockOffset, new ReentrantLock());
    }

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值