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

JDK1.8中ArrayList是如何擴(kuò)容的

 更新時(shí)間:2021年12月12日 11:45:12   作者:Ccy丶雙  
本文基于此出發(fā)講解ArrayList的擴(kuò)容機(jī)制,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

ArrayList簡介:

ArrayList實(shí)現(xiàn)了List接口它是一個(gè)可調(diào)整大小的數(shù)組可以用來存放各種形式的數(shù)據(jù)。并提供了包括CRUD在內(nèi)的多種方法可以對(duì)數(shù)據(jù)進(jìn)行操作但是它不是線程安全的,外ArrayList按照插入的順序來存放數(shù)據(jù)。

在講擴(kuò)容機(jī)制之前,我們需要了解一下ArrayList中最主要的幾個(gè)變量:

private static final int DEFAULT_CAPACITY = 10;//數(shù)組默認(rèn)初始容量

private static final Object[] EMPTY_ELEMENTDATA = {};//定義一個(gè)空的數(shù)組實(shí)例以供其他需要用到空數(shù)組的地方調(diào)用 

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//定義一個(gè)空數(shù)組,跟前面的區(qū)別就是這個(gè)空數(shù)組是用來判斷ArrayList第一添加數(shù)據(jù)的時(shí)候要擴(kuò)容多少。默認(rèn)的構(gòu)造器情況下返回這個(gè)空數(shù)組 

transient Object[] elementData;//數(shù)據(jù)存的地方它的容量就是這個(gè)數(shù)組的長度,同時(shí)只要是使用默認(rèn)構(gòu)造器(DEFAULTCAPACITY_EMPTY_ELEMENTDATA )第一次添加數(shù)據(jù)的時(shí)候容量擴(kuò)容為DEFAULT_CAPACITY = 10 

private int size;//當(dāng)前數(shù)組的長度

本題的所有的講解都是基于JDK8

在這里插入圖片描述

這道題考察了ArrayList的構(gòu)造器和對(duì)擴(kuò)容機(jī)制的了解,本篇博客基于此出發(fā)講解ArrayList的擴(kuò)容機(jī)制

想要做出這道題必須了解ArrayList的構(gòu)造函數(shù),ArrayList的構(gòu)造函數(shù)總共有三個(gè):

  • ArrayList()構(gòu)造一個(gè)空的數(shù)組。JDK7中構(gòu)造一個(gè)初始容量為10的空列表但是JDK8中只是構(gòu)造一個(gè)空的數(shù)組
  • ArrayList(Collection<? extends E> c)構(gòu)造一個(gè)包含指定 collection 的元素的數(shù)組,這些元素是按照該 collection 的迭代器返回它們的順序排列的。
  • ArrayList(int initialCapacity)構(gòu)造一個(gè)具有指定初始容量的空數(shù)組。

我們重點(diǎn)來看這兩個(gè)ArrayList(int initialCapacity),ArrayList()構(gòu)造函數(shù)

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

初始化一個(gè)空數(shù)組,這是JDK8不同于之前版本的地方

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

對(duì)于形參initialCapacity判斷,如果大于0那么就聲明一個(gè)和形參一樣大小的數(shù)組。了解到這里似乎這道題的正確答案也出來了即選擇A,并沒有發(fā)生擴(kuò)容

但是作為一名合格的程序員要有探索精神,題目提到了擴(kuò)容,既然ArrayList底層是一個(gè)數(shù)組,那么就肯定會(huì)滿,什么時(shí)候發(fā)生擴(kuò)容呢?

//1.add方法為添加元素在數(shù)組末尾
public boolean add(E e) {
    //確保數(shù)組容量 size指向數(shù)組的末尾
    ensureCapacityInternal(size + 1);
    //在完成添加之前要確保數(shù)組長度足夠
    elementData[size++] = e;
    return true;
}
//3.elementData為ArrayList底層維護(hù)的數(shù)組,minCapacity為此時(shí)數(shù)組的大小
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    //如果數(shù)組為初始化的值,就初始化數(shù)組容量為10(空參的構(gòu)造方法下首次添加)
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
//2.minCapacity表示此時(shí)數(shù)組的大小
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//4.minCapacity表示此時(shí)數(shù)組的大小
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    //如果此時(shí)數(shù)組容量的大小不夠就擴(kuò)容
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

源碼讀到這里,我們明白了,當(dāng)我們每次向ArrayList添加元素的時(shí)候,都會(huì)首先確保數(shù)組容量夠放下元素如果不夠就會(huì) grow(minCapacity)調(diào)用擴(kuò)容函數(shù),那么秉承著探索的精神,原本大小的數(shù)組擴(kuò)容之后變成多大了呢?還得繼續(xù)看源碼

//擴(kuò)容源碼
private void grow(int minCapacity) {
    //獲取當(dāng)前數(shù)組的長度
    int oldCapacity = elementData.length;
    //>>右移相當(dāng)于整除2,新容量相當(dāng)于就舊容量的1.5倍
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    //如果擴(kuò)容后的容量還不夠那么就以需要的容量為新容量
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    //如果新容量已經(jīng)超過最大容量了,那么就直接使用最大容量
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    //講新容量的數(shù)組拷貝
    elementData = Arrays.copyOf(elementData, newCapacity);
}

源碼大致讀完后,我們明白了ArrayList的自動(dòng)擴(kuò)容機(jī)制,每次新添加元素的時(shí)候都會(huì)判斷是否能夠容下,如果不夠就會(huì)發(fā)生擴(kuò)容,擴(kuò)容的大小為原大小的1.5倍數(shù),明白這些以后讓我們看看下面這段程序擴(kuò)容了幾次呢??容量是多少呢?

ArrayList<Integer> arrayList = new ArrayList<Integer>(20);
for(int i=1;i<=50;i++) {
     arrayList.add(i);
}

前20次添加不會(huì)發(fā)生擴(kuò)容,當(dāng)21元素添加時(shí)數(shù)組容量從20擴(kuò)容到30,當(dāng)添加31元素時(shí)數(shù)組容量從30擴(kuò)容到45,當(dāng)添加46元素時(shí)數(shù)組容量從45擴(kuò)容到67

到此這篇關(guān)于JDK1.8中ArrayList是如何擴(kuò)容的的文章就介紹到這了,更多相關(guān)JDK1.8 ArrayList擴(kuò)容內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用HTTPclient保持長連接

    使用HTTPclient保持長連接

    這篇文章主要介紹了使用HTTPclient保持長連接,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java+opencv3.2.0實(shí)現(xiàn)重映射

    Java+opencv3.2.0實(shí)現(xiàn)重映射

    這篇文章主要為大家詳細(xì)介紹了Java+opencv3.2.0實(shí)現(xiàn)重映射的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Mybatis批量更新對(duì)象數(shù)據(jù)的兩種實(shí)現(xiàn)方式

    Mybatis批量更新對(duì)象數(shù)據(jù)的兩種實(shí)現(xiàn)方式

    這篇文章主要介紹了Mybatis批量更新對(duì)象數(shù)據(jù)的兩種實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java算法之?dāng)?shù)組冒泡排序代碼實(shí)例講解

    Java算法之?dāng)?shù)組冒泡排序代碼實(shí)例講解

    這篇文章主要介紹了Java算法之?dāng)?shù)組冒泡排序代碼實(shí)例講解,文中用代碼舉例講解的很清晰,有感興趣的同學(xué)可以研究下
    2021-03-03
  • SpringBoot項(xiàng)目設(shè)置斷點(diǎn)debug調(diào)試無效忽略web.xml問題的解決

    SpringBoot項(xiàng)目設(shè)置斷點(diǎn)debug調(diào)試無效忽略web.xml問題的解決

    這篇文章主要介紹了SpringBoot項(xiàng)目設(shè)置斷點(diǎn)debug調(diào)試無效忽略web.xml問題的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • SpringCloud使用CircuitBreaker實(shí)現(xiàn)熔斷器的詳細(xì)步驟

    SpringCloud使用CircuitBreaker實(shí)現(xiàn)熔斷器的詳細(xì)步驟

    在微服務(wù)架構(gòu)中,服務(wù)之間的依賴調(diào)用非常頻繁,當(dāng)一個(gè)下游服務(wù)因高負(fù)載或故障導(dǎo)致響應(yīng)變慢或不可用時(shí),可能會(huì)引發(fā)上游服務(wù)的級(jí)聯(lián)故障,最終導(dǎo)致整個(gè)系統(tǒng)崩潰,熔斷器是解決這類問題的關(guān)鍵模式之一,Spring Cloud提供了對(duì)熔斷器的支持,本文將詳細(xì)介紹如何集成和使用它
    2025-02-02
  • SpringBoot?快速實(shí)現(xiàn)?api?接口加解密功能

    SpringBoot?快速實(shí)現(xiàn)?api?接口加解密功能

    在項(xiàng)目中,為了保證數(shù)據(jù)的安全,我們常常會(huì)對(duì)傳遞的數(shù)據(jù)進(jìn)行加密,Spring?Boot接口加密,可以對(duì)返回值、參數(shù)值通過注解的方式自動(dòng)加解密,這篇文章主要介紹了SpringBoot?快速實(shí)現(xiàn)?api?接口加解密功能,感興趣的朋友一起看看吧
    2023-10-10
  • Java 線程死鎖的問題解決辦法

    Java 線程死鎖的問題解決辦法

    這篇文章主要介紹了 Java 線程死鎖的問題解決辦法的相關(guān)資料,希望通過本大家能幫助到大家,遇到類似問題能夠解決,需要的朋友可以參考下
    2017-09-09
  • SpringBoot項(xiàng)目中使用@Scheduled讀取動(dòng)態(tài)參數(shù)

    SpringBoot項(xiàng)目中使用@Scheduled讀取動(dòng)態(tài)參數(shù)

    這篇文章主要介紹了SpringBoot項(xiàng)目中使用@Scheduled讀取動(dòng)態(tài)參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringBoot中給指定接口加上權(quán)限校驗(yàn)的實(shí)現(xiàn)

    SpringBoot中給指定接口加上權(quán)限校驗(yàn)的實(shí)現(xiàn)

    本文介紹了使用SpringSecurity為接口添加權(quán)限校驗(yàn),以防止外部訪問并確保安全性,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12

最新評(píng)論

鹤峰县| 隆安县| 永清县| 桐梓县| 贡觉县| 景泰县| 水城县| 弋阳县| 黄梅县| 神农架林区| 谢通门县| 辰溪县| 宁武县| 乐亭县| 宝兴县| 嘉定区| 天津市| 紫云| 夏河县| 仪征市| 普宁市| 巴彦县| 文水县| 新密市| 西城区| 安远县| 章丘市| 台湾省| 都兰县| 慈利县| 松原市| 濮阳县| 陵川县| 新巴尔虎左旗| 大余县| 皮山县| 永新县| 兴业县| 延吉市| 闵行区| 徐州市|