CopyOnWriteArrayList源码分析

目录

1.将指定索引处的值更改为指定值

2.添加值

3.删除指定索引处的值

4.删掉从fromIndex到toIndex-1的元素

5.从该集合中保留指定集合中的包含的所有元素

6.清除

7.在索引处,加入指定集合的全部值


以下为CopyOnWriteArrayList源码分析:

创建部分:

public class CopyOnWriteArrayList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
	//创建ReentrantLock锁
    final transient ReentrantLock lock = new ReentrantLock();
	//新建一个数组
    private transient volatile Object[] array;
	//数组得到方法
    final Object[] getArray() {
        return array;
    }
	//数组创建方法
    final void setArray(Object[] a) {
        array = a;
    }

	//新建数组
    public CopyOnWriteArrayList() {
        setArray(new Object[0]);
    }

	
    public CopyOnWriteArrayList(Collection<? extends E> c) {
        Object[] elements;
		//如果是CopyOnWriteArrayList类
        if (c.getClass() == CopyOnWriteArrayList.class)
            elements = ((CopyOnWriteArrayList<?>)c).getArray();
		//不是CopyOnWriteArrayList类
        else {
			//转为数组
            elements = c.toArray();
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
			//不是Object数组类
            if (elements.getClass() != Object[].class)
				//复制数组
                elements = Arrays.copyOf(elements, elements.length, Object[].class);
        }
        setArray(elements);
    }

  

1.将指定索引处的值更改为指定值

 //将指定索引处的值更改为指定值
    public E set(int index, E element) {
		//使用当前类的锁
        final ReentrantLock lock = this.lock;
		//加锁
        lock.lock();
        try {
			//得到类的数组
            Object[] elements = getArray();
			//得到指定索引处的值
            E oldValue = get(elements, index);
			//更改前和更改后的值不一样
            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.添加值

//添加值	
    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
			//复制出长度加1的新数组
            Object[] newElements = Arrays.copyOf(elements, len + 1);
			//将值写入数组的末尾
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }
    //在指定索引处添加值
    public void add(int index, E element) {
        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;
			//当在数组末尾加新值
            if (numMoved == 0)
				//复制的数组长度加1
                newElements = Arrays.copyOf(elements, len + 1);
            else {
				//创建新数组
                newElements = new Object[len + 1];
				//两次复制
                System.arraycopy(elements, 0, newElements, 0, index);
                System.arraycopy(elements, index, newElements, index + 1,
                                 numMoved);
            }
			//在索引出加值
            newElements[index] = element;
            setArray(newElements);
        } finally {
            lock.unlock();
        }
    }

3.删除指定索引处的值

//删除指定索引处的值
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)
				//直接复制除末尾值的数组
                setArray(Arrays.copyOf(elements, len - 1));
            else {
                Object[] newElements = new Object[len - 1];
				//两次分开复制(跨过要删除的值)
                System.arraycopy(elements, 0, newElements, 0, index);
                System.arraycopy(elements, index + 1, newElements, index,
                                 numMoved);
                setArray(newElements);
            }
            return oldValue;
        } finally {
            lock.unlock();
        }
    }

4.删掉从fromIndex到toIndex-1的元素

//删掉从fromIndex到toIndex-1的元素
    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;
			//当删掉末尾的若干数时
            if (numMoved == 0)
				//直接复制前面的值
                setArray(Arrays.copyOf(elements, newlen));
            else {
				//分两次复制
                Object[] newElements = new Object[newlen];
                System.arraycopy(elements, 0, newElements, 0, fromIndex);
                System.arraycopy(elements, toIndex, newElements,
                                 fromIndex, numMoved);
                setArray(newElements);
            }
        } finally {
            lock.unlock();
        }
    }

5.从该集合中保留指定集合中的包含的所有元素

//从该集合中保留指定集合中的包含的所有元素
    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;
			//长度不为0
            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;
                }
				//当temp数组的长度不等于elements数组的长度
                if (newlen != len) {
					//将该集合中保留参数集合中包含的所有元素set进当前类的array中
                    setArray(Arrays.copyOf(temp, newlen));
                    return true;
                }
            }
			//长度为0,不会包含,返回false
            return false;
        } finally {
            lock.unlock();
        }
    }

6.清除

//清除
    public void clear() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            setArray(new Object[0]);
        } finally {
            lock.unlock();
        }
    }

7.在索引处,加入指定集合的全部值

  //在索引处,加入指定集合的全部值
    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);
			//当参数值长度为0
            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];
                System.arraycopy(elements, 0, newElements, 0, 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();
        }
    }
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值