源码学习:ArrayList源码分析

目录

 

ArrayList类的定义

ArrayList类中的成员变量

ArrayList的构造方法

size方法

isEmpty方法

indexOf方法

lastIndexOf方法

add方法

remove方法

get方法

set方法

contail方法


ArrayList类的定义

public class ArrayList extends AbstractList

        implements List, RandomAccess, Cloneable, java.io.Serializable

(1)ArrayList类继承了abstractlist,实现了list、randomaccess、cloneable、serializable接口。

 

ArrayList类中的成员变量

private static final long serialVersionUID = 8683452581122892189L;

 

    /**

     * Default initial capacity.

     */

    private static final int DEFAULT_CAPACITY = 10;

 

    /**

     * Shared empty array instance used for empty instances.

     */

    private static final Object[] EMPTY_ELEMENTDATA = {};

 

    /**

     * Shared empty array instance used for default sized empty instances. We

     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when

     * first element is added.

     */

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

 

    /**

     * The array buffer into which the elements of the ArrayList are stored.

     * The capacity of the ArrayList is the length of this array buffer. Any

     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA

     * will be expanded to DEFAULT_CAPACITY when the first element is added.

     */

    transient Object[] elementData; // non-private to simplify nested class access

 

    /**

     * The size of the ArrayList (the number of elements it contains).

     *

     * @serial

     */

private int size;

(1)DEFAULT_CAPACITY:默认的初始化容量。

(2)EMPTY_ELEMENTDATA:指定数组的容量为0,使用这个常量赋值。

(3)DEFAULTCAPACITY_EMPTY_ELEMENTDATA:默认空参构造函数时,使用这个变量赋值。

(4)elementData:表示真正存储数据的对象数组,transient表示不被序列化。

(5)size:表示数组中的真实元素个数。

ArrayList的构造方法

(1)无参数的构造方法

/**

     * Constructs an empty list with an initial capacity of ten.

     */

    public ArrayList() {

        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

}

(2)有参数的构造方法

/**

     * Constructs an empty list with the specified initial capacity.

     *

     * @param  initialCapacity  the initial capacity of the list

     * @throws IllegalArgumentException if the specified initial capacity

     *         is negative

     */

    public ArrayList(int initialCapacity) {

        if (initialCapacity > 0) {

            this.elementData = new Object[initialCapacity];

        } else if (initialCapacity == 0) {

            this.elementData = EMPTY_ELEMENTDATA;

        } else {

            throw new IllegalArgumentException("Illegal Capacity: "+

                                               initialCapacity);

        }

}

size方法

/**

     * Returns the number of elements in this list.

     *

     * @return the number of elements in this list

     */

    public int size() {

        return size;

}

isEmpty方法

 /**

     * Returns true if this list contains no elements.

     *

     * @return true if this list contains no elements

     */

    public boolean isEmpty() {

        return size == 0;

    }

indexOf方法

/**

     * Returns the index of the first occurrence of the specified element

     * in this list, or -1 if this list does not contain the element.

     * More formally, returns the lowest index i such that

     * (o==null ? get(i)==null : o.equals(get(i))),

     * or -1 if there is no such index.

     */

    public int indexOf(Object o) {

        if (o == null) {

            for (int i = 0; i < size; i++)

                if (elementData[i]==null)

                    return i;

        } else {

            for (int i = 0; i < size; i++)

                if (o.equals(elementData[i]))

                    return i;

        }

        return -1;

    }

lastIndexOf方法

/**

     * Returns the index of the last occurrence of the specified element

     * in this list, or -1 if this list does not contain the element.

     * More formally, returns the highest index i such that

     * (o==null ? get(i)==null : o.equals(get(i))),

     * or -1 if there is no such index.

     */

    public int lastIndexOf(Object o) {

        if (o == null) {

            for (int i = size-1; i >= 0; i--)

                if (elementData[i]==null)

                    return i;

        } else {

            for (int i = size-1; i >= 0; i--)

                if (o.equals(elementData[i]))

                    return i;

        }

        return -1;

}

add方法

/**

     * Appends the specified element to the end of this list.

     *

     * @param e element to be appended to this list

     * @return true (as specified by {@link Collection#add})

     */

    public boolean add(E e) {

        ensureCapacityInternal(size + 1);  // Increments modCount!!

        elementData[size++] = e;

        return true;

}

private void ensureCapacityInternal(int minCapacity) {

        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));

}

private void ensureExplicitCapacity(int minCapacity) {

        modCount++;

 

        // overflow-conscious code

        if (minCapacity - elementData.length > 0)

            grow(minCapacity);

 }

private static int calculateCapacity(Object[] elementData, int minCapacity) {

        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

            return Math.max(DEFAULT_CAPACITY, minCapacity);

        }

        return minCapacity;

}

 

/**

     * 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);

    }

 private static int hugeCapacity(int minCapacity) {

        if (minCapacity < 0) // overflow

            throw new OutOfMemoryError();

        return (minCapacity > MAX_ARRAY_SIZE) ?

            Integer.MAX_VALUE :

            MAX_ARRAY_SIZE;

 }

 

 

 

 

 

 

 

(1)ensureCapacityInternal方法会判断当前数组是否是空数组,如果是,则比较其与10的大小,取较大值。否则返回。

(2)ensureExplicitCapacity方法会判断minCapacity与当前数组实际长度的大小,若是大于当前数组的实际长度,则表示需要调用grow方法,否则返回。

(3)grow方法使用oldCapacity + (oldCapacity >> 1)使得当期数组长度增加为之前的1.5倍。

 /**

     * Inserts the specified element at the specified position in this

     * list. Shifts the element currently at that position (if any) and

     * any subsequent elements to the right (adds one to their indices).

     *

     * @param index index at which the specified element is to be inserted

     * @param element element to be inserted

     * @throws IndexOutOfBoundsException {@inheritDoc}

     */

    public void add(int index, E element) {

        rangeCheckForAdd(index);

 

        ensureCapacityInternal(size + 1);  // Increments modCount!!

        System.arraycopy(elementData, index, elementData, index + 1,

                         size - index);

        elementData[index] = element;

        size++;

}

/**

     * A version of rangeCheck used by add and addAll.

     */

    private void rangeCheckForAdd(int index) {

        if (index > size || index < 0)

            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

    }

remove方法

/**

     * Removes the element at the specified position in this list.

     * Shifts any subsequent elements to the left (subtracts one from their

     * indices).

     *

     * @param index the index of the element to be removed

     * @return the element that was removed from the list

     * @throws IndexOutOfBoundsException {@inheritDoc}

*/

 public E remove(int index) {

        rangeCheck(index);

 

        modCount++;

        E oldValue = elementData(index);

 

        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;

}

/**

     * Checks if the given index is in range.  If not, throws an appropriate

     * runtime exception.  This method does *not* check if the index is

     * negative: It is always used immediately prior to an array access,

     * which throws an ArrayIndexOutOfBoundsException if index is negative.

     */

    private void rangeCheck(int index) {

        if (index >= size)

            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

}

 

/**

     * Removes the first occurrence of the specified element from this list,

     * if it is present.  If the list does not contain the element, it is

     * unchanged.  More formally, removes the element with the lowest index

     * i such that

     * (o==null ? get(i)==null : o.equals(get(i)))

     * (if such an element exists).  Returns true if this list

     * contained the specified element (or equivalently, if this list

     * changed as a result of the call).

     *

     * @param o element to be removed from this list, if present

     * @return true if this list contained the specified element

     */

    public boolean remove(Object o) {

        if (o == null) {

            for (int index = 0; index < size; index++)

                if (elementData[index] == null) {

                    fastRemove(index);

                    return true;

                }

        } else {

            for (int index = 0; index < size; index++)

                if (o.equals(elementData[index])) {

                    fastRemove(index);

                    return true;

                }

        }

        return false;

}

get方法

/**

     * Returns the element at the specified position in this list.

     *

     * @param  index index of the element to return

     * @return the element at the specified position in this list

     * @throws IndexOutOfBoundsException {@inheritDoc}

     */

    public E get(int index) {

        rangeCheck(index);

 

        return elementData(index);

}

 

/**

     * Checks if the given index is in range.  If not, throws an appropriate

     * runtime exception.  This method does *not* check if the index is

     * negative: It is always used immediately prior to an array access,

     * which throws an ArrayIndexOutOfBoundsException if index is negative.

     */

    private void rangeCheck(int index) {

        if (index >= size)

            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

    }

 

/**

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

    }

@SuppressWarnings("unchecked")

    E elementData(int index) {

        return (E) elementData[index];

    }

set方法

/**

     * Replaces the element at the specified position in this list with

     * the specified element.

     *

     * @param index index of the element to replace

     * @param element element to be stored at the specified position

     * @return the element previously at the specified position

     * @throws IndexOutOfBoundsException {@inheritDoc}

     */

    public E set(int index, E element) {

        rangeCheck(index);

 

        E oldValue = elementData(index);

        elementData[index] = element;

        return oldValue;

}

/**

     * Checks if the given index is in range.  If not, throws an appropriate

     * runtime exception.  This method does *not* check if the index is

     * negative: It is always used immediately prior to an array access,

     * which throws an ArrayIndexOutOfBoundsException if index is negative.

     */

    private void rangeCheck(int index) {

        if (index >= size)

            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

}

contail方法

/**

     * Returns true if this list contains the specified element.

     * More formally, returns true if and only if this list contains

     * at least one element e such that

     * (o==null ? e==null : o.equals(e)).

     *

     * @param o element whose presence in this list is to be tested

     * @return true if this list contains the specified element

     */

    public boolean contains(Object o) {

        return indexOf(o) >= 0;

    }

你可能感兴趣的:(源码学习,java进阶之路,java)