1. 程式人生 > 實用技巧 >18_集合之ArrayList類

18_集合之ArrayList類

1. ArrayList概述

集合是儲存和操作資料的容器, java中提供了完整的集合框架. 由於篇幅限制, 此篇只討論ArrayList的使用情況.

1.1 ArrayList繼承體系

java.lang.Object 
	java.util.AbstractCollection<E> implements Collection<E>
		java.util.AbstractList<E> implements List<E>
			java.util.ArrayList<E>  implements List<E>, RandomAccess, Cloneable, Serializable

1.2 ArrayList特點

  1. ArrayList大小可調整
  2. 允許儲存所有元素, 包括null值
  3. 底層採用陣列儲存資料, 查詢快, 增刪慢
  4. 執行緒不安全

2. ArrayList成員分析

2.1 成員變數

    /**
     * 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 size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

本想著寫詳細的註釋, 看到原始碼的註釋已經寫的很到位, 如果強行翻譯只是畫蛇添足.

2.2 構造器

  1. public ArrayList(int initialCapacity) 指定長度建立ArrayList物件
  2. public ArrayList() 無參構造
  3. public ArrayList(Collection<? extends E> c) , 根據一個集合,建立物件
    ArrayList為我們提供了三個構造器, 開發中三種都可以用到, 根據需求選用.

2.3 成員方法

2.3.1 集合元素個數

    /**
     * Returns the number of elements in this list.
     *
     * @return the number of elements in this list
     */
    public int size() {
        return size;
    }

2.3.2 集合是否為空

    /**
     * Returns {@code true} if this list contains no elements.
     *
     * @return {@code true} if this list contains no elements
     */
    public boolean isEmpty() {
        return size == 0;
    }

2.3.3 是否包含指定元素

    /**
     * Returns {@code true} if this list contains the specified element.
     * More formally, returns {@code true} if and only if this list contains
     * at least one element {@code e} such that
     * {@code Objects.equals(o, e)}.
     *
     * @param o element whose presence in this list is to be tested
     * @return {@code true} if this list contains the specified element
     */
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

2.3.4 查詢元素索引(找不到返-1)

    /**
     * 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 {@code i} such that
     * {@code Objects.equals(o, get(i))},
     * or -1 if there is no such index.
     */
    public int indexOf(Object o) {
        return indexOfRange(o, 0, size);
    }
    

2.3.5 查詢元素最後出現索引(找不到返-1)

    /**
     * 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 {@code i} such that
     * {@code Objects.equals(o, get(i))},
     * or -1 if there is no such index.
     */
    public int lastIndexOf(Object o) {
        return lastIndexOfRange(o, 0, size);
    }

2.3.6 集合轉陣列

    /**
     * Returns an array containing all of the elements in this list
     * in proper sequence (from first to last element).
     *
     * <p>The returned array will be "safe" in that no references to it are
     * maintained by this list.  (In other words, this method must allocate
     * a new array).  The caller is thus free to modify the returned array.
     *
     * <p>This method acts as bridge between array-based and collection-based
     * APIs.
     *
     * @return an array containing all of the elements in this list in
     *         proper sequence
     */
    public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

2.3.7 獲取指定位置元素

    /**
     * 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) {
        Objects.checkIndex(index, size);
        return elementData(index);
    }

2.3.8 替換指定位置元素

    /**
     * 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) {
        Objects.checkIndex(index, size);
        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

2.3.9 在末尾新增元素

    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }

2.3.10 指定位置新增元素

    /**
     * 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);
        modCount++;
        final int s;
        Object[] elementData;
        if ((s = size) == (elementData = this.elementData).length)
            elementData = grow();
        System.arraycopy(elementData, index,
                         elementData, index + 1,
                         s - index);
        elementData[index] = element;
        size = s + 1;
    }

2.3.11 移除指定位置元素

    /**
     * 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) {
        Objects.checkIndex(index, size);
        final Object[] es = elementData;

        @SuppressWarnings("unchecked") E oldValue = (E) es[index];
        fastRemove(es, index);

        return oldValue;
    }

2.3.12 移除元素

    /**
     * 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
     * {@code i} such that
     * {@code Objects.equals(o, get(i))}
     * (if such an element exists).  Returns {@code 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 {@code true} if this list contained the specified element
     */
    public boolean remove(Object o) {
        final Object[] es = elementData;
        final int size = this.size;
        int i = 0;
        found: {
            if (o == null) {
                for (; i < size; i++)
                    if (es[i] == null)
                        break found;
            } else {
                for (; i < size; i++)
                    if (o.equals(es[i]))
                        break found;
            }
            return false;
        }
        fastRemove(es, i);
        return true;
    }

2.3.13 清空集合

    /**
     * Removes all of the elements from this list.  The list will
     * be empty after this call returns.
     */
    public void clear() {
        modCount++;
        final Object[] es = elementData;
        for (int to = size, i = size = 0; i < to; i++)
            es[i] = null;
    }

2.3.14 在集合中移除一個子集

    /**
     * Removes from this list all of its elements that are contained in the
     * specified collection.
     *
     * @param c collection containing elements to be removed from this list
     * @return {@code true} if this list changed as a result of the call
     * @throws ClassCastException if the class of an element of this list
     *         is incompatible with the specified collection
     * (<a href="Collection.html#optional-restrictions">optional</a>)
     * @throws NullPointerException if this list contains a null element and the
     *         specified collection does not permit null elements
     * (<a href="Collection.html#optional-restrictions">optional</a>),
     *         or if the specified collection is null
     */
    public boolean removeAll(Collection<?> c) {
        return batchRemove(c, false, 0, size);
    }

2.3.15 獲取迭代器(用來遍歷集合)

    /**
     * Returns an iterator over the elements in this list in proper sequence.
     *
     * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
     *
     * @return an iterator over the elements in this list in proper sequence
     */
    public Iterator<E> iterator() {
        return new Itr();
    }

2.3.16 取子集

    /**
     * Returns a view of the portion of this list between the specified
     * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.  (If
     * {@code fromIndex} and {@code toIndex} are equal, the returned list is
     * empty.)  The returned list is backed by this list, so non-structural
     * changes in the returned list are reflected in this list, and vice-versa.
     * The returned list supports all of the optional list operations.
     */   
public List<E> subList(int fromIndex, int toIndex) {
        subListRangeCheck(fromIndex, toIndex, size);
        return new SubList<>(this, fromIndex, toIndex);
    }

3. Demo

package e_collection.a_list;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * ArrayList使用
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        //構造器
        //1. public ArrayList(int initialCapacity) 指定長度建立ArrayList物件
        ArrayList<String> list1 = new ArrayList<>(10);
        //2. public ArrayList() 無參構造
        ArrayList<String> list2 = new ArrayList<>();
        //3. public ArrayList(Collection<? extends E> c) , 根據一個集合,建立物件
        ArrayList<String> list3 = new ArrayList<>(list1);

        //成員方法
        //2.3.9 在末尾新增元素
        for (int i = 0; i < 10; i++) {
            list1.add("hello" + i);
        }

        //2.3.1 集合元素個數
        //int size = list1.size();
        //System.out.println(size);   //10

        //2.3.2 集合是否為空
        //boolean list1Empty = list1.isEmpty();
        //System.out.println(list1Empty);//false

        //2.3.3 是否包含指定元素
        //boolean contains = list1.contains("hello4");
        //System.out.println(contains);   //true

        //2.3.4 查詢元素索引(找不到返-1)
        //int index = list1.indexOf("hello6");
        //System.out.println(index);  //6

        //2.3.5 查詢元素最後出現索引(找不到返-1)
        //int index = list1.lastIndexOf("hello6");
        //System.out.println(index);  //6

        //2.3.6 集合轉陣列
        /*Object[] arr = list1.toArray();
        for(Object o : arr) {
            System.out.print((String)o + " ");//hello0 hello1 hello2 ... hello9
        }*/

        //2.3.7 獲取指定位置元素
        //String s = list1.get(5);
        //System.out.println(s);  //hello5

        //2.3.8 替換指定位置元素
        //String str5 = list1.set(5, "java");
        //System.out.println(str5);   //hello5

        //2.3.10 指定位置新增元素
        /*list1.add(3, "java");
        for(String s : list1) {
            System.out.print(s + " "); //hello0 hello1 hello2 java hello3
        }*/

        //2.3.11 移除指定位置元素
        //String remove = list1.remove(2);
        //System.out.println(remove); //hello2

        //2.3.12 移除元素
        //boolean remove = list1.remove("hello2");
        //System.out.println(remove); //true

        //2.3.13 清空集合
        //list1.clear();
        //int size = list1.size();
        //System.out.println(size);//0

        //2.3.15 獲取迭代器(用來遍歷集合)
        /*Iterator<String> iterator = list1.iterator();
        while ((iterator.hasNext())){
            System.out.print(iterator.next() + " ");    //hello0 hello1 hello2 ...hello9
        }*/

        
    }
}

4. 總結

ArrayList是集合框架中使用最多的一個具體實現類, 常握其成員方法的用法, 可以觸類旁通. 有興趣的朋友可以學習下資料結構與演算法, 學習了之後再學集合框架就會融會貫通.