淺談ArrayList

ArrayList結構圖
arraylist.png
ArrayList主要方法
  • public boolean add(E e);
  • public E set(int index, E element)
  • public boolean remove(Object o);
  • public E get(int index);
ArrayList解讀主要方法

首先來看看add方法源碼:

 public boolean add(E e) {
        //判斷是否需要擴容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
       // 添加元素       
       elementData[size++] = e;
        return true;
    }

來看一下ensureCapacityInternal這個方法:

private void ensureCapacityInternal(int minCapacity) {
        // 如果數據為空(集合里沒有元素),minCapacity取默認長度
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);
    }

來看一下ensureExplicitCapacity這個方法:

private void ensureExplicitCapacity(int minCapacity) {
        // 這個值是為了判斷ConcurrentModificationException異常的
        modCount++;
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

來看一下grow這個方法:

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容量
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

在看一下底層的調用:

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

來看一下public E set(int index, E element)源碼

 public E set(int index, E element) {
      //判斷index位置
        rangeCheck(index);
      //獲取index位置的元素
        E oldValue = elementData(index);
        //把新的元素放入index位置,返回原來的元素
        elementData[index] = element;
        return oldValue;
    }
//判斷index位置
 private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

再看看remove的源碼:

   public E remove(int index) {
        //校驗刪除位置是否合理
        rangeCheck(index);
      // 同add理由一樣
        modCount++;
       // 保存待刪除元素
        E oldValue = elementData(index);
        // 判斷刪除位置:如果>0不在尾部需要調用System.arraycopy,否則在尾部直接刪除
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
        //返回當前要刪除的元素
        return oldValue;
    }

最后看一下get方法:

public E get(int index) {
        // 校驗刪除位置是否合理
        rangeCheck(index);
        //返回index位置的元素
        return elementData(index);
    }

好了看了一下,也就是add方法比較復雜,remove和get都比較簡單。

ArrayList遍歷介紹

常用的三種遍歷方式:

       //one  foreach  遍歷
        for (Object o : list) {
            System.out.println(o);
        }
        // two 隨機訪問
        for (int i = 0; i <list.size(); i++) {
            System.out.println(list.get(i));
        }
        //three 迭代器的遍歷
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }
ArrayList其他特性介紹

我們來介紹一下ArrayList的一些小特效:

  • ArrayList底層是利用數組來實現的 Object[] elementData,因此ArrayList擁有數組的特性,因為數組是邏輯上連續的,物理上也是連續的,因此查詢比較方便,刪除比較麻煩;然而LinkedList底層是利用鏈表來實現的,它擁有鏈表的特性,因為鏈表只是邏輯上連續的物理上非連續的所以它的添加和刪除比較快,查詢就比較麻煩。
  • ArrayList默認的初始值是10,private static final int DEFAULT_CAPACITY = 10;每次擴容的容量為: int newCapacity = oldCapacity + (oldCapacity >> 1);約1.5倍
  • ArrayList是會拋出 ConcurrentModificationException異常的
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,778評論 18 399
  • 一、基本數據類型 注釋 單行注釋:// 區域注釋:/* */ 文檔注釋:/** */ 數值 對于byte類型而言...
    龍貓小爺閱讀 4,291評論 0 16
  • 一.線性表 定義:零個或者多個元素的有限序列。也就是說它得滿足以下幾個條件:??①該序列的數據元素是有限的。??②...
    Geeks_Liu閱讀 2,715評論 1 12
  • 到了嚴冬 可又感覺像暖春 生于憂患 死于安樂 過度的患得患失又會讓人抑郁 本是一心有想法的自己卻也在此隨波逐流 偶...
    我曾這樣存在過閱讀 241評論 0 0
  • 在生活和工作中,很少表達自己的觀點,原因:一是文化背景,沒有這方面的訓練,在表達自己觀點的時候被扼殺了;二是...
    傲立梅枝閱讀 347評論 0 1