<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-13  評論-22  文章-0  trackbacks-0

    ArrayList

    本文github地址

    總體介紹

    ArrayList實(shí)現(xiàn)了List接口,是順序容器,即元素存放的數(shù)據(jù)與放進(jìn)去的順序相同,允許放入null元素,底層通過數(shù)組實(shí)現(xiàn)。除該類未實(shí)現(xiàn)同步外,其余跟Vector大致相同。每個ArrayList都有一個容量(capacity),表示底層數(shù)組的實(shí)際大小,容器內(nèi)存儲元素的個數(shù)不能多于當(dāng)前容量。當(dāng)向容器中添加元素時,如果容量不足,容器會自動增大底層數(shù)組的大小。前面已經(jīng)提過,Java泛型只是編譯器提供的語法糖,所以這里的數(shù)組是一個Object數(shù)組,以便能夠容納任何類型的對象。

    ArrayList_base

    size(), isEmpty(), get(), set()方法均能在常數(shù)時間內(nèi)完成,add()方法的時間開銷跟插入位置有關(guān),addAll()方法的時間開銷跟添加元素的個數(shù)成正比。其余方法大都是線性時間。

    為追求效率,ArrayList沒有實(shí)現(xiàn)同步(synchronized),如果需要多個線程并發(fā)訪問,用戶可以手動同步,也可使用Vector替代。

    方法剖析

    set()

    既然底層是一個數(shù)組ArrayListset()方法也就變得非常簡單,直接對數(shù)組的指定位置賦值即可。

    public E set(int index, E element) {
        rangeCheck(index);//下標(biāo)越界檢查
        E oldValue = elementData(index);
        elementData[index] = element;//賦值到指定位置,復(fù)制的僅僅是引用
        return oldValue;
    }

    get()

    get()方法同樣很簡單,唯一要注意的是由于底層數(shù)組是Object[],得到元素后需要進(jìn)行類型轉(zhuǎn)換。

    public E get(int index) {
        rangeCheck(index);
        return (E) elementData[index];//注意類型轉(zhuǎn)換
    }

    add()

    跟C++ 的vector不同,ArrayList沒有bush_back()方法,對應(yīng)的方法是add(E e)ArrayList也沒有insert()方法,對應(yīng)的方法是add(int index, E e)。這兩個方法都是向容器中添加新元素,這可能會導(dǎo)致capacity不足,因此在添加元素之前,都需要進(jìn)行剩余空間檢查,如果需要則自動擴(kuò)容。擴(kuò)容操作最終是通過grow()方法完成的。

    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//原來的1.5倍
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);//擴(kuò)展空間并復(fù)制
    }

    由于Java GC自動管理了內(nèi)存,這里也就不需要考慮源數(shù)組釋放的問題。

    ArrayList_grow

    空間的問題解決后,插入過程就顯得非常簡單。

    ArrayList_add

    add(int index, E e)需要先對元素進(jìn)行移動,然后完成插入操作,也就意味著該方法有著線性的時間復(fù)雜度。

    addAll()

    addAll()方法能夠一次添加多個元素,根據(jù)位置不同也有兩個把本,一個是在末尾添加的addAll(Collection<? extends E> c)方法,一個是從指定位置開始插入的addAll(int index, Collection<? extends E> c)方法。跟add()方法類似,在插入之前也需要進(jìn)行空間檢查,如果需要則自動擴(kuò)容;如果從指定位置插入,也會存在移動元素的情況。
    addAll()的時間復(fù)雜度不僅跟插入元素的多少有關(guān),也跟插入的位置相關(guān)。

    remove()

    remove()方法也有兩個版本,一個是remove(int index)刪除指定位置的元素,另一個是remove(Object o)刪除第一個滿足o.equals(elementData[index])的元素。刪除操作是add()操作的逆過程,需要將刪除點(diǎn)之后的元素向前移動一個位置。需要注意的是為了讓GC起作用,必須顯式的為最后一個位置賦null值。

    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//清除該位置的引用,讓GC起作用
        return oldValue;
    }

    關(guān)于Java GC這里需要特別說明一下,有了垃圾收集器并不意味著一定不會有內(nèi)存泄漏。對象能否被GC的依據(jù)是是否還有引用指向它,上面代碼中如果不手動賦null值,除非對應(yīng)的位置被其他元素覆蓋,否則原來的對象就一直不會被回收。

    posted on 2016-04-22 08:39 CarpenterLee 閱讀(1351) 評論(7)  編輯  收藏

    評論:
    # re: Java ArrayList源碼剖析[未登錄] 2016-04-22 10:05 | linda
    java源碼 高難度啊  回復(fù)  更多評論
      
    # re: Java ArrayList源碼剖析 2016-04-22 11:32 | kexue
    分析很清楚,請問博主插圖使用的是什么軟件繪制的?  回復(fù)  更多評論
      
    # re: Java ArrayList源碼剖析 2016-04-22 12:30 | CarpenterLee
    @kexue
    我用的是一款叫做Dia (software)的繪圖軟件,類似于MS visio,挺好用的。這里有它的介紹https://en.wikipedia.org/wiki/Dia_(software)。  回復(fù)  更多評論
      
    # re: Java ArrayList源碼剖析 2016-04-22 12:36 | CarpenterLee
    @linda
    Java代碼寫得比較清晰,還有注釋,看起來不是很費(fèi)勁的。  回復(fù)  更多評論
      
    # re: Java ArrayList源碼剖析 2016-05-11 19:51 | 陳軍
    這邊博文有價值  回復(fù)  更多評論
      
    # re: Java ArrayList源碼剖析 2016-05-11 22:11 | CarpenterLee
    @陳軍
    常來轉(zhuǎn)轉(zhuǎn),希望能給大家?guī)硇┦斋@。  回復(fù)  更多評論
      
    # re: Java ArrayList源碼剖析 2016-05-12 16:54 | www.niuchui.com
    學(xué)習(xí)了,感覺要消化一下。  回復(fù)  更多評論
      

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲一本之道高清乱码| 亚洲精品无码av人在线观看 | 国产美女精品久久久久久久免费| 亚洲日本香蕉视频观看视频| 99re6在线视频精品免费下载| 亚洲AV无码国产丝袜在线观看| 中文字幕免费不卡二区| 午夜亚洲国产理论秋霞| 在线观看www日本免费网站| 久久亚洲国产精品成人AV秋霞| 精品熟女少妇av免费久久| 亚洲国产成人在线视频| 国产在线国偷精品产拍免费| 亚洲国产精品无码观看久久| 国产男女猛烈无遮挡免费视频网站| 国产亚洲欧美日韩亚洲中文色| 免费国产成人午夜电影| 国产无限免费观看黄网站| 国产偷v国产偷v亚洲高清| 久久午夜夜伦鲁鲁片无码免费| 亚洲福利一区二区| 69成人免费视频无码专区| 亚洲高清毛片一区二区| 中文字幕亚洲图片| 91热久久免费精品99| 日韩亚洲国产综合高清| 亚洲AⅤ无码一区二区三区在线| 中文在线观看永久免费| 亚洲国产精品成人久久久| 日本xxwwxxww在线视频免费| 亚洲五月午夜免费在线视频| 久久综合亚洲鲁鲁五月天| 天堂在线免费观看中文版| 久久av免费天堂小草播放| 亚洲精品视频观看| 免费一级毛片免费播放| 在线涩涩免费观看国产精品| 亚洲 日韩经典 中文字幕| 久久久久久亚洲精品不卡| 7723日本高清完整版免费| 一道本不卡免费视频|