JDK源碼閱讀--ArrayList

 

 


public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable


ArrayList繼承了AbstractList抽象類,實現了List、RandomAccess、Cloneable、Serializable接口。
ArrayList的默認初始容量爲10,閱讀源碼可知--底層數據結構是數組。添加的元素是能夠重複的。
底層數據結構是數組,查詢快,增長、刪除元素慢(由於每增長或刪除元素,數組的其他位置的元素都須要進行變更)
 1  /**
 2      * Default initial capacity.
 3      * 默認初始容量爲10
 4      */
 5     private static final int DEFAULT_CAPACITY = 10;
 6 
 7     /**
 8      * Shared empty array instance used for empty instances.
 9      */
10     private static final Object[] EMPTY_ELEMENTDATA = {};
11 
12     /**
13      * Shared empty array instance used for default sized empty instances. We
14      * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
15      * first element is added.
16      */
17     private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
18 
19     /**
20      * The array buffer into which the elements of the ArrayList are stored.
21      * The capacity of the ArrayList is the length of this array buffer. Any
22      * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
23      * will be expanded to DEFAULT_CAPACITY when the first element is added.
24      */
25     transient Object[] elementData; // 非私有,以簡化嵌套類訪問。被transient修飾的,不能被序列化
26 
27     /**
28      * The size of the ArrayList (the number of elements it contains).
29      * ArrayList的長度(元素個數)
30      * @serial
31      */
32     private int size;

 

ArrayList的構造方法的源碼:java

 1  /**
 2      * 使用默認容量構造一個數組
 3      *
 4      * @param  initialCapacity  這個列表的初始化容量
 5      * @throws IllegalArgumentException 若是初始化容量initialCapacity是一個負數,則會拋出這個IllegalArgumentException異常
 6      */
 7     public ArrayList(int initialCapacity) {
 8         if (initialCapacity > 0) {
 9             this.elementData = new Object[initialCapacity];
10         } else if (initialCapacity == 0) {
11             this.elementData = EMPTY_ELEMENTDATA;
12         } else {
13             throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
14         }
15     }
16 
17     /**
18      * Constructs an empty list with an initial capacity of ten.
19      * 構造初始容量爲10的空數組
20      */
21     public ArrayList() {
22         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
23     }
24 
25     /**
26      *  構造包含指定的元素的列表集合,按照順序返回這個集合的迭代器。
27      *
28      * @param c 要放到集合中的Collection
29      * @throws NullPointerException 若是傳入的Collection爲null,則會拋出NullPointerException空指針異常
30      */
31     public ArrayList(Collection<? extends E> c) {
32         elementData = c.toArray();
33         if ((size = elementData.length) != 0) {
34             // c.toArray might (incorrectly) not return Object[] (see 6260652)
35             if (elementData.getClass() != Object[].class)
36                 elementData = Arrays.copyOf(elementData, size, Object[].class);
37         } else {
38             // replace with empty array.
39             this.elementData = EMPTY_ELEMENTDATA;
40         }
41     }

 

 

重寫了clone方法。數組

 1   /**
 2      * Returns a shallow copy of this <tt>ArrayList</tt> instance.  (The elements themselves are not copied.)
 3      * 返回此ArrayList實例的淺拷貝。(元素自己不會被複制。)
 4      * @return a clone of this <tt>ArrayList</tt> instance
 5      */
 6     public Object clone() {
 7         try {
 8             ArrayList<?> v = (ArrayList<?>) super.clone();
 9             v.elementData = Arrays.copyOf(elementData, size);
10             v.modCount = 0;
11             return v;
12         } catch (CloneNotSupportedException e) {
13             // this shouldn't happen, since we are Cloneable
14             throw new InternalError(e);
15         }
16     }

 

add方法:數據結構

 1     /**
 2      * 將指定元素追加到列表末尾。因此ArrayList是有序的,也就是元素的存儲順序和添加順序是一致的。
 3      *
 4      * @param e element to be appended to this list 追加到列表中的元素
 5      * @return <tt>true</tt> (as specified by {@link Collection#add})
 6      */
 7     public boolean add(E e) {
 8         //確保內部的容量
 9         ensureCapacityInternal(size + 1);  // Increments modCount!!
10         elementData[size++] = e;//在list末尾追加元素
11         return true;
12     }
13 
14     /**
15      * 在list的指定索引處插入指定元素
16      * Inserts the specified element at the specified position in this
17      * list. Shifts the element currently at that position (if any) and
18      * any subsequent elements to the right (adds one to their indices).
19      *
20      * @param index   被插入的索引位置 index at which the specified element is to be inserted
21      * @param element 被插入的元素 element to be inserted
22      * @throws IndexOutOfBoundsException {@inheritDoc}
23      */
24     public void add(int index, E element) {
25         //檢查索引是否越界
26         rangeCheckForAdd(index);
27         //確保內部的容量
28         ensureCapacityInternal(size + 1);  // Increments modCount!!
29         System.arraycopy(elementData, index, elementData, index + 1,
30                 size - index);
31         elementData[index] = element;
32         size++;
33     }

 

remove方法:app

 1     /**
 2      * 移除指定位置的元素,將指定位置元素以後的元素左移動。
 3      * Removes the element at the specified position in this list.
 4      * Shifts any subsequent elements to the left (subtracts one from their
 5      * indices).
 6      *
 7      * @param index 要被移除的元素的索引 the index of the element to be removed
 8      * @return 返回ArrayList中被移除的元素 the element that was removed from the list
 9      * @throws IndexOutOfBoundsException {@inheritDoc}
10      */
11     public E remove(int index) {
12         //檢查索引是否越界,若是越界,則拋出IndexOutOfBoundsException異常
13         rangeCheck(index);
14 
15         modCount++;
16         E oldValue = elementData(index);//取出要被移除的元素
17 
18         //將被刪除的元素的索引位置右邊的全部元素往左移動一位
19         int numMoved = size - index - 1;
20         if (numMoved > 0) {
21             System.arraycopy(elementData, index + 1, elementData, index,
22                     numMoved);
23         }
24         //將ArrayList中原先最後位置的索引位置置爲null,以便GC完成它的工做
25         elementData[--size] = null; // clear to let GC do its work
26 
27         return oldValue;//返回被移除的元素
28     }
29 
30     /**
31      * Removes the first occurrence of the specified element from this list,
32      * if it is present.  If the list does not contain the element, it is
33      * unchanged.  More formally, removes the element with the lowest index
34      * <tt>i</tt> such that
35      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
36      * (if such an element exists).  Returns <tt>true</tt> if this list
37      * contained the specified element (or equivalently, if this list
38      * changed as a result of the call).
39      *
40      * @param o element to be removed from this list, if present
41      * @return <tt>true</tt> if this list contained the specified element
42      */
43     public boolean remove(Object o) {
44         if (o == null) {
45             for (int index = 0; index < size; index++)
46                 if (elementData[index] == null) {
47                     fastRemove(index);
48                     return true;
49                 }
50         } else {
51             for (int index = 0; index < size; index++)
52                 if (o.equals(elementData[index])) {
53                     fastRemove(index);
54                     return true;
55                 }
56         }
57         return false;
58     }

 

 

 

 1  /**
 2      * 增長容量,以確保它至少能夠持有由最小容量參數指定的元素容量。
 3      * Increases the capacity to ensure that it can hold at least the
 4      * number of elements specified by the minimum capacity argument.
 5      *
 6      * @param minCapacity 指望的最小容量
 7      */
 8     private void grow(int minCapacity) {
 9         // overflow-conscious code
10         int oldCapacity = elementData.length;
11         int newCapacity = oldCapacity + (oldCapacity >> 1);
12         if (newCapacity - minCapacity < 0)
13             newCapacity = minCapacity;
14         if (newCapacity - MAX_ARRAY_SIZE > 0)
15             newCapacity = hugeCapacity(minCapacity);
16         // minCapacity is usually close to size, so this is a win:
17         elementData = Arrays.copyOf(elementData, newCapacity);//
18     }

 

 1     /**
 2      * 返回ArrayList中指定位置(索引index處)的元素
 3      * Returns the element at the specified position in this list.
 4      *
 5      * @param  index  索引 index of the element to return
 6      * @return list中指定索引處的元素 the element at the specified position in this list
 7      * @throws IndexOutOfBoundsException {@inheritDoc}
 8      */
 9     public E get(int index) {
10         //檢查索引是否越界
11         rangeCheck(index);
12         //返回指定索引處index的元素
13         return elementData(index);
14     }

 

 

 1  /**
 2      * 將ArrayList中某個索引index位置上的元素A替換成你指定的元素B
 3      * Replaces the element at the specified position in this list with
 4      * the specified element.
 5      *
 6      *
 7      * @param index 替換的元素的索引 index of the element to replace
 8      * @param element 替換後的元素 element to be stored at the specified position
 9      * @return 該位置上替換前的元素 the element previously at the specified position
10      * @throws IndexOutOfBoundsException {@inheritDoc}
11      */
12     public E set(int index, E element) {
13         //檢查索引是否越界
14         rangeCheck(index);
15         //獲取index索引處原先的元素
16         E oldValue = elementData(index);
17         //將index索引處的元素替換成你指定的元素element
18         elementData[index] = element;
19         //返回index索引處原先的元素
20         return oldValue;
21     }

 

 

   /**
     * A version of rangeCheck used by add and addAll.
     * 進行範圍檢查,也就是索引是否越界
     */
    private void rangeCheckForAdd(int index) {
        //若是索引越界,則拋出IndexOutOfBoundsException異常
        if (index > size || index < 0) {
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        }
    }

    /**
     * 構造IndexOutOfBoundsException異常的詳細信息
     * Constructs an IndexOutOfBoundsException detail message.
     * Of the many possible refactorings of the error handling code,
     * this "outlining" performs best with both server and client VMs.
     */
    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+size;
    }
相關文章
相關標籤/搜索