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的构造方法的源码:

 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方法:

 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;
    }

 

posted @ 2019-03-07 09:34  以前、以后  阅读(159)  评论(0编辑  收藏  举报