關(guān)于ArrayList

ArrayList簡(jiǎn)介

  1. ArrayList內(nèi)部是以動(dòng)態(tài)數(shù)組存放數(shù)據(jù)的,所謂動(dòng)態(tài)數(shù)組,不是數(shù)組本身可以改變長(zhǎng)度,而是保留原有數(shù)組引用的情況下創(chuàng)建一個(gè)新的數(shù)組,使用體驗(yàn)就像是可自動(dòng)擴(kuò)容的數(shù)組。
  2. ArrayList內(nèi)部是數(shù)組,支持?jǐn)?shù)組的所有特性,通過(guò)索引支持隨機(jī)訪問(wèn),所以訪問(wèn)效率高,但是插入和刪除效率低下。
  3. ArrayList實(shí)現(xiàn)了AbstractList抽象類、List接口、所以其更具有了AbstractList和List的功能,AbstractList內(nèi)部已經(jīng)實(shí)現(xiàn)了獲取Iterator和ListIterator的方法,所以ArrayList只需關(guān)心對(duì)數(shù)組操作的方法即List接口的實(shí)現(xiàn)。
  4. ArrayList實(shí)現(xiàn)了RandomAccess接口、此接口只有聲明、沒(méi)有方法體、表示ArrayList支持隨機(jī)訪問(wèn)。
  5. ArrayList實(shí)現(xiàn)了Cloneable接口、此接口只有聲明、沒(méi)有方法體、表示ArrayList支持克隆。
  6. ArrayList實(shí)現(xiàn)了Serializable接口、此接口只有聲明、沒(méi)有方法體、表示ArrayList支持序列化、即可以將ArrayList以流的形式通過(guò)ObjectInputStream/ObjectOutputStream來(lái)寫/讀。

ArrayList的擴(kuò)容

  1. 初始容量為10:使用無(wú)參構(gòu)造的創(chuàng)建ArrayList的時(shí)候默認(rèn)容量為10。
  2. 擴(kuò)容規(guī)則:每次add元素(單個(gè)或者一組)的時(shí)候,都要先檢查容量是否夠用。如果發(fā)現(xiàn)容量不夠,就設(shè)置新容量為原有容量1.5倍+1,如果新容量還不夠用,就直接把新容量設(shè)置為能盛放當(dāng)前元素量的值。然后就是使用Arrays.copyOf()方法把原數(shù)據(jù)copy到新數(shù)組中去。由此可見,使用ArrayList盡量明確使用上限,自動(dòng)擴(kuò)容雖好,但是效率不高。
  3. 為什么是1.5倍:跟源代碼中的算法有關(guān)“oldCapacity + (oldCapacity >> 1);”
  4. Arrays.copyOf():最終使用的是操作系統(tǒng)的api進(jìn)行數(shù)組復(fù)制,效率比我們手寫代碼要高。
  5. 擴(kuò)容限制:擴(kuò)容并非是無(wú)限制的,有內(nèi)存限制,虛擬機(jī)限制。

手寫ArrayList幫助理解

public class MyArrayList<T> implements Iterable<T>  {
    private T[] theItems;
    private int theSize;
    private static final int DEAULT_CAPACITY=10;

    public MyArrayList(){
        theSize=0;
        ensureCapacity(DEAULT_CAPACITY);

    }

    public void add(T data){
        if(size()==theItems.length){
            ensureCapacity(size()*2+1);
        }
        theItems[size()]=data;
        theSize++;
    }

    public void add(int index,T data){
        if(size()==theItems.length){
            ensureCapacity(size()*2+1);
        }
        for(int i=theSize;i>index;i--){
            theItems[i]=theItems[i-1];
        }
        theItems[index]=data;
        theSize++;
    }

    public T get(int index){
        if(index<0|index>=size()){
            throw new IndexOutOfBoundsException("index error");
        }
        return theItems[index];
    }

    public T remove(int index){
        T removeData=get(index);
        for(int i=index;i<size()-1;i++){
            theItems[i]=theItems[i+1];
        }
        theSize--;
        return removeData;
    }

    public int size(){
        return theSize;
    }

    private void ensureCapacity(int newCapacity){
        if(theSize>newCapacity){
            return;
        }

        T[] old=theItems;
        theItems= (T[]) new Object[newCapacity];
        for(int i=0;i<size();i++){
            theItems[i]=old[i];
        }
    }



    @Override
    public Iterator<T> iterator() {
        return null;
    }

    @Override
    public void forEach(Consumer<? super T> action) {

    }

    @Override
    public Spliterator<T> spliterator() {
        return null;
    }
}

參考文章:
Java容器之ArrayList

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容