Java ArrayList阅读笔记

ArrayList:

  • 默认初始化容量为10;
  • 每次插入前先进行扩容检测及扩容,扩容大小为原容量的一半(例:10+5,扩容后为15);
    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

CopyOnWriteArrayList:

  • 因为它是一个按需分配的数组,所以没有size的概念,它的数组长度便是size,初始容量是一个为0的空数组;
  • 它使用 ReentrantLock重入锁来保证多线程安全;
  • 疑问:每次都 copy一个新数组,在数据量大的情况下,这会不会有点耗费性能和内存占用?
    /** 保护所有冲突变量的锁 */
    final transient ReentrantLock lock = new ReentrantLock();

    /** 数组只能通过 getArray/setArray访问 */
    private transient volatile Object[] array;

    /**
     * 构造初始化
     */
    public CopyOnWriteArrayList() {
        setArray(new Object[0]); // 初始化数组
    }

    /**
     * 向数组插入一个对象
     */
    public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] elements = getArray();
            int len = elements.length;
            // 每次都 copy一个新数组,在数据量大的情况下,这会不会有点耗费性能和内存占用?
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
            lock.unlock();
        }
    }

延申:

CopyOnWriteArraySet:

  • 直接使用 CopyOnWriteArrayList作为存储结构来实现,插入时比较数组里面所有的值,如果重复则忽略;
  • 它也使用 ReentrantLock重入锁来保证多线程安全;

你可能感兴趣的:(Java ArrayList阅读笔记)