欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java ArrayList源碼深入分析

 更新時(shí)間:2022年08月27日 10:36:07   作者:niuyongzhi  
ArrayList 類是一個(gè)可以動(dòng)態(tài)修改的數(shù)組,與普通數(shù)組的區(qū)別就是它是沒(méi)有固定大小的限制,我們可以添加或刪除元素。ArrayList 繼承了 AbstractList,并實(shí)現(xiàn)了List接口

1.ArrayList 是基數(shù)組結(jié)構(gòu)的,需要連續(xù)的內(nèi)存空間

從構(gòu)造函數(shù)可以看出,ArrayList內(nèi)部用一個(gè)Object數(shù)組來(lái)保存數(shù)據(jù)。

對(duì)于無(wú)參構(gòu)造,ArrayList會(huì)創(chuàng)建一個(gè)大小為10的初始數(shù)組,第一次擴(kuò)容時(shí)會(huì)創(chuàng)建默認(rèn)大小數(shù)組。

 //無(wú)參構(gòu)造函數(shù),會(huì)構(gòu)造一個(gè)空數(shù)組。第一次擴(kuò)容時(shí)會(huì)創(chuàng)默認(rèn)大小為10的數(shù)組
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    transient Object[] elementData;
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    private static final Object[] EMPTY_ELEMENTDATA = {};
    //如果給定集合大小,會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)大小的數(shù)組
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                    initialCapacity);
        }
    }

2.對(duì)于set和get方法ArrayList效率高,因?yàn)榭梢灾苯油ㄟ^(guò)下標(biāo)獲取存儲(chǔ)對(duì)象。

 //直接通過(guò)角標(biāo)從數(shù)組中取出元素
    public E get(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        return (E) elementData[index];
    }
    //set 方法,直接通過(guò)index 拿到元素,進(jìn)行修改就行。
    public E set(int index, E element) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        E oldValue = (E) elementData[index];
        elementData[index] = element;
        return oldValue;
    }

3.對(duì)于add方法,有兩種情況:

第一種是在尾部添加,不需要移動(dòng)數(shù)組。

//Add 方法 ,在末端插入不需要
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

第二種情況在指定位置添加或插入數(shù)據(jù),則需要移動(dòng)數(shù)組,效率比較低。如果插入在第0個(gè)位置則需要移動(dòng)整個(gè)數(shù)組。

  public void add(int index, E element) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        //被插入的元素在index。則移動(dòng)的數(shù)組應(yīng)該從index開(kāi)始,向后移動(dòng)一個(gè),
		//移動(dòng)的數(shù)組長(zhǎng)度 size-index 從index開(kāi)始的數(shù)組長(zhǎng)度
        System.arraycopy(elementData, index, elementData, index + 1,
                size - index);
        elementData[index] = element;
        size++;
    }

在add時(shí)還需要考慮到數(shù)組的擴(kuò)容問(wèn)題,看ensureCapacityInternal方法

 private void ensureCapacityInternal(int minCapacity) {
        //通過(guò)無(wú)參構(gòu)造創(chuàng)建為設(shè)置初始大小時(shí),判斷條件為true
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //創(chuàng)建默認(rèn)大小的數(shù)組,初始大小是10
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);
    }

添加元素后,元素?cái)?shù)量大于數(shù)組長(zhǎng)度時(shí),進(jìn)行擴(kuò)容grow,擴(kuò)容大小是原數(shù)組的1.5倍

 private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // overflow-conscious code
        //新增后,數(shù)組容量已經(jīng)大于了數(shù)組長(zhǎng)度,則進(jìn)行擴(kuò)容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
		//新的數(shù)組大小是原來(lái)的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);  
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //創(chuàng)建一個(gè)新長(zhǎng)度的數(shù)組。
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

4.對(duì)應(yīng)remove 刪除元素操作。如果刪除元素在最后一個(gè),不需要移動(dòng)數(shù)組,否則會(huì)將被刪除元素之后的所有元素都要向前移動(dòng),效率比較低。

 //刪除
    public E remove(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
        modCount++;
        //取出被刪除的元素
        E oldValue = (E) elementData[index];
        int numMoved = size - index - 1;
		//移動(dòng)的數(shù)組長(zhǎng)度,大于0才需要移動(dòng),小于0說(shuō)明被刪元素在最后一個(gè)
        if (numMoved > 0)
            //第一個(gè)參數(shù)是源數(shù)組,
            //第二個(gè)參數(shù)是移動(dòng)的起始位置:index+1,從被刪元素的后一個(gè)位置開(kāi)始
            //第三個(gè)參數(shù)是目標(biāo)數(shù)組
            //第四個(gè)參數(shù)是移動(dòng)目標(biāo)位置:index,被刪除元素的位置
            //第五個(gè)參數(shù)是移動(dòng)的數(shù)組長(zhǎng)度 size - index - 1,從index+1位置開(kāi)始之后的數(shù)組長(zhǎng)度
            //最終會(huì)調(diào)用到native方法進(jìn)行移動(dòng)。
            System.arraycopy(elementData, index+1, elementData, index,numMoved);
        elementData[--size] = null; // clear to let GC do its work
        return oldValue;
    }

5.System.arraycopy方法參數(shù)分析。

第二個(gè)參數(shù) index+1是被移動(dòng)數(shù)組的起始位置,即被刪元素后一個(gè)位置

第四個(gè)參數(shù)index,是被移動(dòng)數(shù)組的起始位置,即被刪元素的位置。

最后一個(gè)參數(shù)size-index-1,被移動(dòng)數(shù)組的長(zhǎng)度,即被刪元素后一個(gè)位置到元素末尾的長(zhǎng)度

public static native void arraycopy(java.lang.Object src, int srcPos, java.lang.Object dest, int destPos, int length);

通過(guò)對(duì)源碼的閱讀,也許會(huì)對(duì)ArrayList有一個(gè)更加直接的了解。

到此這篇關(guān)于Java ArrayList源碼深入分析的文章就介紹到這了,更多相關(guān)Java ArrayList內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android JNI c/c++調(diào)用java的實(shí)例

    Android JNI c/c++調(diào)用java的實(shí)例

    這篇文章主要介紹了Android JNI c/c++調(diào)用java的實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • 解析android中的幫助、about、關(guān)于作者、HELP等提示頁(yè)面

    解析android中的幫助、about、關(guān)于作者、HELP等提示頁(yè)面

    本篇文章是對(duì)android中的幫助、about、關(guān)于作者、HELP等提示頁(yè)面進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Android刷新加載框架詳解

    Android刷新加載框架詳解

    這篇文章主要為大家詳細(xì)介紹了Android刷新加載框架的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android中BroadcastReceiver實(shí)現(xiàn)短信關(guān)鍵字自動(dòng)回復(fù)功能

    Android中BroadcastReceiver實(shí)現(xiàn)短信關(guān)鍵字自動(dòng)回復(fù)功能

    實(shí)現(xiàn)手機(jī)短信監(jiān)聽(tīng)的方式有兩種:一是通過(guò)ContentObserver觀察者實(shí)現(xiàn)監(jiān)聽(tīng),另一種就是通過(guò)廣播即BroadcastReceiver實(shí)現(xiàn)短信監(jiān)聽(tīng),文章中通過(guò)使用BroadcastReceiver實(shí)現(xiàn)有新短信的及時(shí)監(jiān)聽(tīng)及包含設(shè)定的關(guān)鍵字時(shí)自動(dòng)回復(fù)
    2018-06-06
  • Android顯示網(wǎng)絡(luò)圖片實(shí)例

    Android顯示網(wǎng)絡(luò)圖片實(shí)例

    這篇文章主要介紹了Android顯示網(wǎng)絡(luò)圖片的方法,以實(shí)例形式展示了Android程序顯示網(wǎng)絡(luò)圖片的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2014-10-10
  • Android數(shù)據(jù)存儲(chǔ)幾種方式講解

    Android數(shù)據(jù)存儲(chǔ)幾種方式講解

    在開(kāi)發(fā)過(guò)程中,數(shù)據(jù)存取是較為頻繁的,今天我們來(lái)了解下android幾種常見(jiàn)的數(shù)據(jù)存取方式。在Android中,sharePreferences是一種輕量級(jí)的數(shù)據(jù)存儲(chǔ)方式,采用鍵值對(duì)的存儲(chǔ)方式,存儲(chǔ)少量數(shù)據(jù),支持基本類型的簡(jiǎn)單數(shù)據(jù)存儲(chǔ)
    2022-12-12
  • Android仿微信右滑返回功能的實(shí)例代碼

    Android仿微信右滑返回功能的實(shí)例代碼

    這篇文章主要介紹了Android仿微信右滑返回功能的實(shí)例代碼,需要的朋友可以參考下
    2017-09-09
  • Android下hook點(diǎn)擊事件的示例

    Android下hook點(diǎn)擊事件的示例

    這篇文章主要介紹了Android下hook點(diǎn)擊事件的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Android清空應(yīng)用內(nèi)部文件緩存

    Android清空應(yīng)用內(nèi)部文件緩存

    這篇文章主要介紹了Android清空應(yīng)用內(nèi)部文件緩存的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • Android高仿微信5.2.1主界面及消息提醒

    Android高仿微信5.2.1主界面及消息提醒

    這篇文章主要為大家詳細(xì)介紹了Android高仿微信5.2.1主界面及消息提醒,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09

最新評(píng)論