深入剖析ArrayList的底层源码-常用方法及其源码剖析

1. get()方法

get(int index)方法是返回集合中指定位置的元素。

 

源码剖析

 

/**

 * 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 [email protected] }

 */

public E get(int index) {

// 检查下标索引是否越界

    rangeCheck(index);

 

// 返回指定索引处的值

    return elementData(index);

}

 

首先会检查索引值是否越界,如果索引值大于数组大小,则会抛出异常。

源码如下:

 

private void rangeCheck(int index) {

// 索引值大于数组大小

    if (index >= size)

     // 抛出异常

        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));

}

 

如果所引是合法的,则调用elementData(int index)方法获取指定位置的元素。

2. set() 方法

set(int index, E element) 方法将index索引处的元素替换成element对象,返回被替换的旧元素。

 

源码剖析

 

/**

 * 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 [email protected] }

 */

public E set(int index, E element) {

// 检查下标索引是否越界

    rangeCheck(index);

 

// 指定下标处的旧值

    E oldValue = elementData(index);

    // 指定下标处赋新的值

    elementData[index] = element;

    // 返回旧值

    return oldValue;

}

 

3. add() 方法

add(E e) 方法 将指定的元素追加到此集合的末尾

源码剖析

 

/**

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

 *

 * @param e element to be appended to this list

 * @return <tt>true</tt> (as specified by [email protected] Collection#add})

 */

public boolean add(E e) {

// 插入元素之前,会检查是否需要扩容

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

    // 将元素添加到数组中最后一个元素的后面,最后将集合中实际的元素个数加 1

    elementData[size++] = e;

    return true;

}

 

add(int index, E element) 在集合元素序列 index 位置处插入

源码剖析

 

/**

 * 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 [email protected] }

 */

public void add(int index, E element) {

// 检查下标索引是否越界

    rangeCheckForAdd(index);

 

// 插入元素之前,会检查是否需要扩容

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

    // 将 index 位置及其后面的所有元素都向后移一位

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

                     size – index);

    // 将新元素插入到 index 位置处,元素个数加 1

    elementData[index] = element;

    size++;

}

 

4. remove() 方法

remove(int index) 方法是删除该集合中指定位置的元素

源码剖析

 

/**

 * 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 [email protected] }

 */

 public E remove(int index) {

  // 检查下标索引是否越界

        rangeCheck(index);

 

        modCount++;

        // 返回被删除的元素值

        E oldValue = elementData(index);

 

// 需要移动的元素的个数

        int numMoved = size – index – 1;

        if (numMoved > 0)

         // 将 index + 1 及其后面的元素向前移动一位,覆盖被删除的元素值

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

                             numMoved);

        // 把数组最后一个元素赋值为null,将元素个数减一

        elementData[–size] = null; // clear to let GC do its work

// 返回旧值

        return oldValue;

    }

 

remove(Object o) 方法是删除指定的元素,如果有重复的元素,则只会删除下标最小的元素

源码剖析

 

 /**

  * 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

  * <tt>i</tt> such that

  * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>

  * (if such an element exists).  Returns <tt>true</tt> 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 <tt>true</tt> 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;

}

 

fastRemove(int index) 方法是快速删除,删除跳过边界检查的方法,也不返回删除的元素值

源码剖析

 

/*

 * Private remove method that skips bounds checking and does not

 * return the value removed.

 */

private void fastRemove(int index) {

   modCount++;

   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

}

 

5. size() 方法

返回集合中的元素个数

 

源码剖析

 

/**

 * Returns the number of elements in this list.

 *

 * @return the number of elements in this list

 */

public int size() {

    return size;

}

 

6. indexOf(Object o) 方法

返回对象o在集合中第一次出现的位置的索引

 

源码剖析

 

/**

 * 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 <tt>i</tt> such that

 * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,

 * or -1 if there is no such index.

 */

public int indexOf(Object o) {

// 如果查找的元素为空

        if (o == null) {

         // 循环遍历数组

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

             // 如果 i 位置的原素为空 

                if (elementData[i]==null)

                 // 返回下标

                    return i;

        // 否则,查找的元素不为空

        } else {

            // 循环遍历数组

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

             // 找到第一个和要查找的元素相等的元素

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

                 // 返回下标

                    return i;

        }

        // 返回 -1.则表示没有找到

        return -1;

    }