最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ArrayList源碼探秘之Java動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)

 更新時(shí)間:2023年08月03日 14:28:25   作者:_GGBond_  
這篇文章將帶大家從ArrayList源碼來(lái)探秘一下Java動(dòng)態(tài)數(shù)組的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),對(duì)我們深入了解JavaScript有一定的幫助,需要的可以參考一下

一、成員變量

讀者需先對(duì)源碼的成員變量閱覽一遍,看個(gè)眼熟,有助于后面源碼的理解

private static final long serialVersionUID = 8683452581122892189L;
    /**
     * 默認(rèn)初始容量大小
     */
    private static final int DEFAULT_CAPACITY = 10;
    /**
     * 空數(shù)組(用于空實(shí)例)。
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};
     //用于默認(rèn)大小空實(shí)例的共享空數(shù)組實(shí)例。
      //我們把它從EMPTY_ELEMENTDATA數(shù)組中區(qū)分出來(lái),以知道在添加第一個(gè)元素時(shí)容量需要增加多少。
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    /**
     * 存儲(chǔ)ArrayList元素的數(shù)組緩沖區(qū)
     */
    transient Object[] elementData; 
    /**
     * ArrayList 所包含的元素個(gè)數(shù)
     */
    private int size;

二、構(gòu)造器

1、默認(rèn)構(gòu)造器

/**
 *默認(rèn)構(gòu)造函數(shù),使用初始容量10構(gòu)造一個(gè)空列表(無(wú)參數(shù)構(gòu)造)
 */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

以無(wú)參數(shù)構(gòu)造方法創(chuàng)建 ArrayList時(shí),實(shí)際上初始化賦值的是一個(gè)空數(shù)組。此時(shí)并沒(méi)有為它創(chuàng)建對(duì)象,當(dāng)真正對(duì)數(shù)組進(jìn)行添加元素操作時(shí),才真正分配容量。即向數(shù)組中添加第一個(gè)元素時(shí),數(shù)組容量擴(kuò)為 10。

2、帶初始容量參數(shù)構(gòu)造器

/**
 * 帶初始容量參數(shù)的構(gòu)造函數(shù)。(用戶自己指定容量)
 */
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {//初始容量大于0
        //創(chuàng)建initialCapacity大小的數(shù)組
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {//初始容量等于0
        //創(chuàng)建空數(shù)組
        this.elementData = EMPTY_ELEMENTDATA;
    } else {//初始容量小于0,拋出異常
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

3、指定collection元素參數(shù)構(gòu)造器

/**
*構(gòu)造包含指定collection元素的列表,這些元素利用該集合的迭代器按順序返回
*如果指定的集合為null,throws NullPointerException。
*/
 public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}

三、add()方法擴(kuò)容機(jī)制

在進(jìn)入ArrayList的核心源碼擴(kuò)容機(jī)制前,我們首先需要對(duì)源碼中涉及到的一些變量進(jìn)行一個(gè)初步的了解,這將有助于你對(duì)源碼的深入了解

minCapacity:數(shù)組所需的最小容量

elementData:存儲(chǔ)ArrayList元素的數(shù)組緩沖區(qū)

public boolean add(E e) {
   ensureCapacityInternal(size + 1);  // size = 0
   elementData[size++] = e;
   return true;
}
private void ensureCapacityInternal(int minCapacity) {//minCapacity = 1
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));//elementData = {}
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    //判斷elementData是否為空數(shù)組
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//DEFAULTCAPACITY_EMPTY_ELEMENTDATA =  {}
        return Math.max(DEFAULT_CAPACITY, minCapacity);//DEFAULT_CAPACITY = 10;minCapacity = 1
    }
    return minCapacity;
}
private void ensureCapacityInternal(int minCapacity) {//minCapacity = 1
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));//ensureExplicitCapacity(10)
}
private void ensureExplicitCapacity(int minCapacity) {//minCapacity = 10
    modCount++;
    if (minCapacity - elementData.length > 0)//elementData.length = 0
        grow(minCapacity);
}
private void grow(int minCapacity) {//minCapacity = 10
    int oldCapacity = elementData.length;//oldCapacity = 0
    int newCapacity = oldCapacity + (oldCapacity >> 1);//newCapacity  = 1.5*oldCapacity = 0
    if (newCapacity - minCapacity < 0)//minCapacity = 10
        newCapacity = minCapacity;//newCapacity = 10
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    //利用Arrays.copyOf()方法進(jìn)行擴(kuò)容
    elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
     if (minCapacity < 0) // overflow
         throw new OutOfMemoryError();
     return (minCapacity > MAX_ARRAY_SIZE) ?
         Integer.MAX_VALUE :
         MAX_ARRAY_SIZE;
 }

1.增加一個(gè)新元素,此時(shí)所需的最小容量是 minCapacity = size+1

2.首先判斷底層數(shù)組 elementData 是否是空數(shù)組

如果是空數(shù)組,則更新 minCapacity 為默認(rèn)容量10,

如果不是空數(shù)組,則對(duì) minCapacity 不做變更

3.判斷所需最小容量 minCapacity 是否大于緩沖數(shù)組 elementData 的長(zhǎng)度:

如果大于,則進(jìn)行擴(kuò)容 grow(),

否則不做處理

4.擴(kuò)容 grow()中,首先一上來(lái)就將 elementData 的長(zhǎng)度擴(kuò)長(zhǎng)為原來(lái)長(zhǎng)度的1.5倍,再對(duì)擴(kuò)容后的 elementData 的長(zhǎng)度和所需最小的容量 minCapacity進(jìn)行判斷
如果擴(kuò)容后的 elementData 的長(zhǎng)度還小于 minCapacity 的長(zhǎng)度,說(shuō)明還是不夠,此時(shí)就直接將minCapacity的長(zhǎng)度賦值給elementData

否則的話直接進(jìn)行下一步即可

5.最后需要對(duì) elementData 的長(zhǎng)度進(jìn)行一個(gè)是否超過(guò)最大限度值MAX_ARRAY_SIZE判斷

如果超過(guò)最大限度值,就看看所需的最小容量minCapacity是否大于最大限度值Integer.MAX_VALUE

如果不是,就將數(shù)組的長(zhǎng)度擴(kuò)容為數(shù)組的最大限度值MAX_ARRAY_SIZE,如果是,則返回Integer.MAX_VALUE

四、場(chǎng)景分析

1、對(duì)于ensureExplicitCapacity()方法

1.1 add 進(jìn)第 1 個(gè)元素到 ArrayList 時(shí)

當(dāng)我們要 add 進(jìn)第 1 個(gè)元素到 ArrayList 時(shí),elementData.length 為 0 (因?yàn)檫€是一個(gè)空的 list),因?yàn)閳?zhí)行了 ensureCapacityInternal() 方法 ,所以 minCapacity 此時(shí)為 10。此時(shí),minCapacity - elementData.length > 0成立,所以會(huì)進(jìn)入 grow(minCapacity) 方法。

1.2 當(dāng) add 第 2 個(gè)元素時(shí)

當(dāng) add 第 2 個(gè)元素時(shí),minCapacity 為 2,此時(shí) elementData.length(容量)在添加第一個(gè)元素后擴(kuò)容成 10 了。此時(shí),minCapacity - elementData.length > 0 不成立,所以不會(huì)進(jìn)入 (執(zhí)行)grow(minCapacity) 方法。添加第 3、4···到第 10 個(gè)元素時(shí),依然不會(huì)執(zhí)行 grow 方法,數(shù)組容量都為 10。

1.3 直到添加第 11 個(gè)元素

minCapacity(為 11)elementData.length(為 10)要大。進(jìn)入 grow 方法進(jìn)行擴(kuò)容。

2、對(duì)于grow() 方法

2.1 當(dāng) add 第 1 個(gè)元素時(shí)

oldCapacity 為 0,經(jīng)比較后第一個(gè) if 判斷成立,newCapacity = minCapacity(為 10)。但是第二個(gè) if 判斷不會(huì)成立,即 newCapacity 不比 MAX_ARRAY_SIZE 大,則不會(huì)進(jìn)入 hugeCapacity 方法。數(shù)組容量為 10,add 方法中 return true,size 增為 1。

2.2 當(dāng) add 第 11 個(gè)元素進(jìn)入 grow 方法時(shí)

newCapacity 為 15,比 minCapacity(為 11)大,第一個(gè) if 判斷不成立。新容量沒(méi)有大于數(shù)組最大 size,不會(huì)進(jìn)入 hugeCapacity 方法。數(shù)組容量擴(kuò)為 15,add 方法中 return true,size 增為 11。以此類推······

五、心得體會(huì)

變量 minCapacity 理解為我們添加元素進(jìn)ArrayList集合中,底層數(shù)組所需的最小容量

變量 elementData.length 理解為我們添加元素進(jìn)ArrayList集合中,底層數(shù)組的最大限度容量

當(dāng)最小容量 minCapacity> 最大限度容量 elementData.length ,必定會(huì)觸發(fā)擴(kuò)容機(jī)制。

我們總是頻繁地向ArrayList集合添加元素,開(kāi)發(fā)人員也想到了這點(diǎn),所以在ArrayList集合的擴(kuò)容機(jī)制中,當(dāng)我們添加第一個(gè)元素時(shí),直接就把minCapacity設(shè)置為10,此處可以理解為,因?yàn)槲覀兒罄m(xù)要頻繁添加元素,為了不總是觸發(fā)該集合的擴(kuò)容機(jī)制,便“謊稱”所需的最小容量是10,所以系統(tǒng)就直接把elementData.length設(shè)置為10

六、源碼簡(jiǎn)易流程圖

以上就是ArrayList源碼探秘之Java動(dòng)態(tài)數(shù)組的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Java動(dòng)態(tài)數(shù)組的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • mybatis中的一級(jí)緩存深入剖析

    mybatis中的一級(jí)緩存深入剖析

    這篇文章主要介紹了mybatis中的一級(jí)緩存深入剖析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • 詳解Java 集合類 List 的那些坑

    詳解Java 集合類 List 的那些坑

    這篇文章主要介紹了Java 集合類 List 的那些坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • JavaSE基礎(chǔ)之反射機(jī)制(反射Class)詳解

    JavaSE基礎(chǔ)之反射機(jī)制(反射Class)詳解

    反射機(jī)制有什么用?通過(guò)java語(yǔ)言中的反射機(jī)制可以操作字節(jié)碼文件,可以讀和修改字節(jié)碼文件。所以本文將為大家講講反射機(jī)制的使用,需要的可以參考一下
    2022-09-09
  • Java中值傳遞和引用傳遞的區(qū)別

    Java中值傳遞和引用傳遞的區(qū)別

    這篇文章主要介紹了Java中值傳遞和引用傳遞的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • SpringBoot整合MyBatisPlus配置動(dòng)態(tài)數(shù)據(jù)源的方法

    SpringBoot整合MyBatisPlus配置動(dòng)態(tài)數(shù)據(jù)源的方法

    這篇文章主要介紹了SpringBoot整合MyBatisPlus配置動(dòng)態(tài)數(shù)據(jù)源的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-05-05
  • Spring?Boot整合Kafka教程詳解

    Spring?Boot整合Kafka教程詳解

    這篇文章主要為大家介紹了Spring?Boot整合Kafka教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Spring之IOC底層原理詳解

    Spring之IOC底層原理詳解

    這篇文章主要介紹了Spring之IOC底層原理,內(nèi)容詳細(xì),文章簡(jiǎn)單易懂,具有一定的參考價(jià)值,需要的朋友可以參考下
    2023-01-01
  • 實(shí)例解析Java程序中正則表達(dá)式的貪婪模式匹配

    實(shí)例解析Java程序中正則表達(dá)式的貪婪模式匹配

    貪婪模式又叫最大匹配,X?、X*、X+、X{n,}都是最大匹配,例如你要用“<.+>”去匹配“a<tr>aava </tr>abb”,也許你所期待的結(jié)果是想匹配“<tr>”,但是實(shí)際結(jié)果卻會(huì)匹配到“<tr>aava </tr>”,下面我們就來(lái)看具體看一下貪婪模式的使用.
    2016-05-05
  • mybatis中${}和#{}的區(qū)別以及底層原理分析

    mybatis中${}和#{}的區(qū)別以及底層原理分析

    這篇文章主要介紹了mybatis中${}和#{}的區(qū)別以及底層原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • jasypt對(duì)配置文件的數(shù)據(jù)加密與解密方式

    jasypt對(duì)配置文件的數(shù)據(jù)加密與解密方式

    這篇文章主要介紹了jasypt對(duì)配置文件的數(shù)據(jù)加密與解密方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論

商水县| 吉安县| 福州市| 和田市| 娄底市| 邵阳县| 洞头县| 靖宇县| 涿鹿县| 南溪县| 栖霞市| 中江县| 盘锦市| 镇雄县| 通海县| 宁海县| 普兰县| 湘潭市| 贡山| 盘山县| 会宁县| 桦甸市| 高阳县| 高州市| 信宜市| 壶关县| 新晃| 江北区| 安达市| 天台县| 巴楚县| 辽宁省| 潢川县| 肇源县| 滦平县| 龙川县| 湖州市| 彝良县| 同心县| 新乡县| 鹤峰县|