ArrayList源碼分析筆記(jdk1.8)

1.特色:數組

  ArrayList 是一個動態數組,它是線程不安全的,容許元素爲null安全

  可重複,插入有序併發

  讀寫快,增刪慢性能

  擴容:默認容量 10,默認擴容1.5倍this

  建議指定容量大小,減小擴容帶來的性能消耗spa

2.構造方法.net

  只分析複雜的線程

  public ArrayList(Collection<? extends E> c)code

    c.toArray()  在Collection接口中定義的接口方法,ArrayList中調用的是Arrays.copyOf(elementData, size)方法(注:擴容也是使用此方法,高頻率方法),調用的是System.arraycopy          blog

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

2.add

  每次 add以前,都會判斷add後的容量,是否須要擴容

  默認擴容倍數1.5倍,若是擴容1.5倍後小於傳入的容量大小,則使用傳入的容量大小,單最大不能大於Integer.MAX_VALUE;

  每次擴容都會修改modCount

  public boolean add(E e)

  public void add(int index, E element)

public void add(int index, E element) {
    rangeCheckForAdd(index);//越界判斷 若是越界拋異常

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index); //將index開始的數據 向後移動一位
    elementData[index] = element;
    size++;
}

  addAll同理都須要先判斷ensureCapacityInternal方法進行判斷是否須要擴容,而後System.arraycopy進行數組賦值擴容

3.romove

  public E remove(int index)

  public boolean remove(Object o)

  都是經過System.arraycopy進行數組賦值來達到效果,刪除後原來,尾部元素,置空,gc

 

  public boolean removeAll(Collection<?> c)

    經過循環,和w標記,保存兩個集合的非共有元素,共有元素置爲null,gc

private boolean batchRemove(Collection<?> c, boolean complement) {
        final Object[] elementData = this.elementData;
        int r = 0, w = 0;
        boolean modified = false;
        try {
            for (; r < size; r++)
                if (c.contains(elementData[r]) == complement)
                    elementData[w++] = elementData[r];
        } finally {
            // Preserve behavioral compatibility with AbstractCollection,
            // even if c.contains() throws.
            if (r != size) {
                System.arraycopy(elementData, r,
                                 elementData, w,
                                 size - r);
                w += size - r;
            }
            if (w != size) {
                // clear to let GC do its work
                for (int i = w; i < size; i++)
                    elementData[i] = null;
                modCount += size - w;
                size = w;
                modified = true;
            }
        }
        return modified;
    }

4.set和get

  modCount不會改變,效率高

5.迭代器

  public Iterator<E> iterator() { return new Itr(); }

  內部類:private class Itr implements Iterator<E>

    modCount != expectedModCount會拋出併發修改異常ConcurrentModificationException

    先next,再remove(實質上是刪除上一次next的元素),不然回報IllegalStateException異常

6.與Vector區別

  Vector:線程安全,都在方法上加synchronized關鍵字

      擴容:默認容量10,默認2倍擴容

int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);

 

 

https://blog.csdn.net/zxt0601/article/list/2

https://blog.csdn.net/ljcITworld/article/details/52041836

相關文章
相關標籤/搜索