ArrayList , Vector 數組集合,arraylistvector

來源:互聯網
上載者:User

ArrayList , Vector 數組集合,arraylistvector

ArrayList 的一些認識:

■ 類定義

public class ArrayList<E> extends AbstractList<E>        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  • 繼承 AbstractList,實現了 List,它是一個數組隊列,提供了相關的添加、刪除、修改、遍曆等功能
  • 實現 RandmoAccess 介面,實現快速隨機訪問:通過元素的序號快速擷取元素對象
  • 實現 Cloneable 介面,重寫 clone(),能被複製(淺拷貝)
  • 實現 java.io.Serializable 介面,支援序列化

■ 全域變數

/**  * 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 == EMPTY_ELEMENTDATA will be expanded to  * DEFAULT_CAPACITY when the first element is added.  * ArrayList底層實現為動態數組; 對象在儲存時不需要維持,java的serialzation提供了持久化
* 機制,我們不想此對象被序列化,所以使用 transient */private transient Object[] elementData;
/** * The size of the ArrayList (the number of elements it contains). * 數組長度 :注意區分長度(當前數組已有的元素數量)和容量(當前數組可以擁有的元素數量)的概念 * @serial */private int size;/** * The maximum size of array to allocate.Some VMs reserve some header words in an array. * Attempts to allocate larger arrays may result in OutOfMemoryError: * Requested array size exceeds VM limit * 數組所能允許的最大長度;如果超出就會報`記憶體溢出異常` -- 可怕後果就是宕機 */private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

 

■ 構造器

/**  * 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) {    super();    if (initialCapacity < 0)        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);    this.elementData = new Object[initialCapacity];}
/** * Constructs an empty list with an initial capacity of ten. * 預設容量為10 */public ArrayList() { this(10);}
/** * Constructs a list containing the elements of the specified collection, * in the order they are returned by the collection's iterator. * 接受一個Collection對象直接轉換為ArrayList * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null 萬惡的null 指標異常 */public ArrayList(Collection<? extends E> c) { elementData = c.toArray();//擷取底層動態數組 size = elementData.length;//擷取底層動態數組的長度 // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class);}

 

■主要方法

 - add()

  • 從源碼上看,ArrayList 一般在尾部插入元素,支援動態擴容
  • 不推薦使用頻繁插入/刪除是因為在執行add()/remove() 會調用非常耗時的 System.arraycopy(),頻繁插入/刪除情境請選用 LinkedList
/**  * Appends the specified element to the end of this list.  * 使用尾插入法,新增元素插入到數組末尾  *  由於錯誤偵測機制使用的是拋異常,所以直接返回true  * @param e element to be appended to this list  * @return <tt>true</tt> (as specified by {@link Collection#add})  */public boolean add(E e) {    //調整容量,修改elementData數組的指向; 當數組長度加1超過原容量時,會自動擴容    ensureCapacityInternal(size + 1);  // Increments modCount!! add屬於結構性修改    elementData[size++] = e;//尾部插入,長度+1    return true;}
/** * 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) { //下標邊界校正,不符合規則 拋出 `IndexOutOfBoundsException` rangeCheckForAdd(index); //調整容量,修改elementData數組的指向; 當數組長度加1超過原容量時,會自動擴容 ensureCapacityInternal(size + 1); // Increments modCount!! //注意是在原數組上進行位移操作,下標為 index+1 的元素統一往後移動一位 System.arraycopy(elementData, index, elementData, index + 1,size - index); elementData[index] = element;//當前下標賦值 size++;//數組長度+1}

  - ensureCapacity() : 擴容,1.8 有個預設值的判斷

//1.8 有個預設值的判斷public void ensureCapacity(int minCapacity) {        int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)            // any size if not default element table            ? 0            // larger than default for default empty table. It's already            // supposed to be at default size.            : DEFAULT_CAPACITY;        if (minCapacity > minExpand) {            ensureExplicitCapacity(minCapacity);        }}private void ensureExplicitCapacity(int minCapacity) {        modCount++;        // overflow-conscious code        if (minCapacity - elementData.length > 0)            grow(minCapacity);}

 - set() / get(): 直接操作下標指標

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

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

 - remove(): 移除其實和add差不多,也是用的是 System.arrayCopy(...)

/**  * 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);//下標邊界校正    E oldValue = elementData(index);//擷取當前座標元素    fastRemove(int index);//這裡我修改了一下源碼,改成直接用fastRemove方法,邏輯不變    return oldValue;//返回原數組元素}
/** * 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?get(i)==null: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). * 直接移除某個元素: * 當該元素不存在,不會發生任何變化 * 當該元素存在且成功移除時,返回true,否則false * 當有重複元素時,只刪除第一次出現的同名元素 : * 例如只移除第一次出現的null(即下標最小時出現的null) * @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) {//ArrayList允許null,需要額外進行null的處理(只處理第一次出現的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()

/*     * Private remove method that skips bounds checking and does not return the value removed.     * 私人方法,除去下標邊界校正以及不返回移除操作的結果     */    private void fastRemove(int index) {        modCount++;//remove操作屬於結構性改動,modCount計數+1        int numMoved = size - index - 1;//需要左移的長度        if (numMoved > 0)            //大於該下標的所有數組元素統一左移一位            System.arraycopy(elementData, index+1, elementData, index,numMoved);        elementData[--size] = null; // Let gc do its work 長度-1,同時加快gc    }

■ 遍曆、排序

/** * Created by meizi on 2017/7/31. * List<資料類型> 排序、遍曆 */public class ListSortTest {    public static void main(String[] args) {        List<Integer> nums = new ArrayList<Integer>();        nums.add(3);        nums.add(5);        nums.add(1);        nums.add(0);        // 遍曆及刪除的操作        /*Iterator<Integer> iterator = nums.iterator();        while (iterator.hasNext()) {            Integer num = iterator.next();            if(num.equals(5)) {                System.out.println("被刪除元素:" + num);                iterator.remove();  //可刪除            }        }        System.out.println(nums);*/        //工具類(Collections) 進行排序        /*Collections.sort(nums);   //底層為數組對象的排序,再通過ListIterator進行遍曆比較,取替        System.out.println(nums);*/        //②自訂排序方式        /*nums.sort(new Comparator<Integer>() {            @Override            public int compare(Integer o1, Integer o2) {                if(o1 > o2) {                    return 1;                } else if (o1 < o2) {                    return -1;                } else {                    return 0;                }            }        });        System.out.println(nums);*/        //遍曆 since 1.8        Iterator<Integer> iterator = nums.iterator();        iterator.forEachRemaining(obj -> System.out.print(obj));   //使用lambda 運算式        /**         * Objects 展示對象各種方法,equals, toString, hash, toString         */        /*default void forEachRemaining(Consumer<? super E> action) {            Objects.requireNonNull(action);            while (hasNext())                action.accept(next());        }*/    }}

 

■ list 與 Array 的轉換問題

  • Object[] toArray(); 可能會產生 ClassCastException
  • <T> T[] toArray(T[] contents) -- 調用 toArray(T[] contents) 能正常返回 T[]
public class ListAndArray {    public static void main(String[] args) {        List<String> list = new ArrayList<String>();        list.add("java");        list.add("C++");        String[] strings = list.toArray(new String[list.size()]);  //使用泛型可避免類型轉換的異常,因為java不支援向下轉換        System.out.println(strings[0]);    }}

 

■ 關於Vector 就不詳細介紹了,因為官方也並不推薦使用: (JDK 1.0)

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.