亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java動(dòng)態(tài)數(shù)組ArrayList實(shí)現(xiàn)動(dòng)態(tài)原理

 更新時(shí)間:2023年08月10日 08:48:44   作者:很閑很快樂(lè)  
ArrayList是一種動(dòng)態(tài)數(shù)組,它可以在運(yùn)行時(shí)自動(dòng)調(diào)整大小以適應(yīng)元素的添加和刪除,在Java中,你可以使用ArrayList類來(lái)實(shí)現(xiàn)動(dòng)態(tài)數(shù)組,本文將給大家介紹一下ArrayList動(dòng)態(tài)數(shù)組,是怎么實(shí)現(xiàn)動(dòng)態(tài)的

簡(jiǎn)介

ArrayList是一個(gè)動(dòng)態(tài)數(shù)組,可以通過(guò)泛型來(lái)決定數(shù)據(jù)中存放的元素類型

怎么實(shí)現(xiàn)的動(dòng)態(tài)

之所以是動(dòng)態(tài)數(shù)組,是因?yàn)樵谑褂脽o(wú)參構(gòu)造函數(shù)創(chuàng)建ArrayList之后,默認(rèn)為空數(shù)組

public ArrayList() {  
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;  
}

在你每次去add一個(gè)元素的時(shí)候,通過(guò)ensureCapacityInternal方法去檢查添加后元素的個(gè)數(shù)是否會(huì)超出當(dāng)前數(shù)組的長(zhǎng)度,如果超出,數(shù)組將會(huì)進(jìn)行擴(kuò)容,以滿足添加數(shù)據(jù)的需求

public boolean add(E e) {
	// size為當(dāng)前數(shù)據(jù)存放元素的數(shù)量
    ensureCapacityInternal(size + 1);
    // elementData為ArrayList內(nèi)部存放數(shù)據(jù)的數(shù)組
    elementData[size++] = e;  
    return true;
}
private void ensureCapacityInternal(int minCapacity) { 
	// 判斷數(shù)組是否為空,為空則將最小容量設(shè)置為默認(rèn)值10
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);  
    }  
	// 判斷當(dāng)前容量是否滿足最小容量
    ensureExplicitCapacity(minCapacity);  
}
private void ensureExplicitCapacity(int minCapacity) {
	// modCount用于記錄修改次數(shù),作用于fast-fail機(jī)制
	// 如果在迭代的時(shí)候發(fā)現(xiàn)modCount被修改了,則會(huì)拋出異常來(lái)避免可能會(huì)出現(xiàn)的不確定行為
    modCount++;  
    // 如果當(dāng)前容量小于最小容量,則進(jìn)行擴(kuò)容
    if (minCapacity - elementData.length > 0)  
        grow(minCapacity);  
}
private void grow(int minCapacity) {  
    int oldCapacity = elementData.length;  
    // 計(jì)算新的容量,擴(kuò)大為原容量的1.5倍, oldCapacity >> 1 運(yùn)算表示右移一位,也就是相當(dāng)于除以二并取整
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)  
        newCapacity = minCapacity; 
    // 如果新容量超過(guò)了數(shù)組的最大容量,調(diào)用hugeCapacity方法來(lái)獲取一個(gè)更大的容量
    if (newCapacity - MAX_ARRAY_SIZE > 0)  
        newCapacity = hugeCapacity(minCapacity);  
    // 拷貝原數(shù)組,將原數(shù)組的元素復(fù)制到新數(shù)組中 
    elementData = Arrays.copyOf(elementData, newCapacity);  
}
private static int hugeCapacity(int minCapacity) {  
    if (minCapacity < 0) 
        throw new OutOfMemoryError();
	// 如果最小容量大于最大容量,則將容量設(shè)置為Integer.MAX_VALUE
    return (minCapacity > MAX_ARRAY_SIZE) ?  
        Integer.MAX_VALUE :  
        MAX_ARRAY_SIZE;  
}

從上面的源碼解釋可以看到,如果新建數(shù)據(jù)沒(méi)有給定初始值,ArrayList是每次在進(jìn)行add操作的時(shí)候去進(jìn)行擴(kuò)容的,擴(kuò)容則會(huì)涉及到Arrays.copyOf深拷貝,會(huì)造成內(nèi)存和性能的消耗,所以在生產(chǎn)項(xiàng)目中,推薦大家盡量在創(chuàng)建ArrayList對(duì)象的時(shí)候就指定其容量。

Fast-Fail機(jī)制

大家肯定注意到了上面提到的通過(guò)modCount實(shí)現(xiàn)的Fast-Fail機(jī)制

Fast-Fail是一種機(jī)制,用于檢測(cè)在迭代過(guò)程中是否有其他線程對(duì)集合進(jìn)行了修改。當(dāng)一個(gè)線程在迭代 ArrayList 時(shí),如果其他線程對(duì) ArrayList 進(jìn)行了結(jié)構(gòu)性修改(如添加、刪除元素),那么迭代器會(huì)立即拋出 ConcurrentModificationException 異常,以避免出現(xiàn)不確定的行為。 例子:

public class Example1 {  
    public static void main(String[] args) {  
        ArrayList<String> list = new ArrayList<>(3);  
        list.add("qwe");  
        list.add("asd");  
        list.add("zxc");  
        Iterator<String> iterator = list.iterator();  
        while (iterator.hasNext()){  
            String next = iterator.next();  
            System.out.println(next);  
            list.remove(next);  
        }  
    }  
}
輸出:
qwe
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at com.example.lepractice.collection.Example1.main(Example1.java:21)

造成快速失敗的常見(jiàn)操作包括:

  • 在迭代過(guò)程中,使用 ArrayList 的 add、remove、clear 等方法修改集合的結(jié)構(gòu)。
  • 多個(gè)線程同時(shí)對(duì) ArrayList 進(jìn)行修改操作。

為了避免快速失敗,可以采取以下措施:

  • 在迭代過(guò)程中,不要修改集合的結(jié)構(gòu)。如果需要修改,可以使用迭代器的 remove 方法,對(duì)應(yīng)上面的例子也就是iterator.remove()。
  • 在多線程環(huán)境下,對(duì)于需要并發(fā)修改的情況,可以使用線程安全的集合類,如 CopyOnWriteArrayList。

如果使用語(yǔ)法糖 for (String next : list) {
System.out.println(next);
list.remove(next);
} 這樣的遍歷方式,其實(shí)內(nèi)部也是使用的迭代器,所以會(huì)存在同樣的問(wèn)題

到此這篇關(guān)于Java動(dòng)態(tài)數(shù)組ArrayList實(shí)現(xiàn)動(dòng)態(tài)原理的文章就介紹到這了,更多相關(guān)Java ArrayList實(shí)現(xiàn)動(dòng)態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot關(guān)閉druid監(jiān)控 druid2改配置文件無(wú)效的解決

    springboot關(guān)閉druid監(jiān)控 druid2改配置文件無(wú)效的解決

    這篇文章主要介紹了springboot關(guān)閉druid監(jiān)控 druid2改配置文件無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • spring中@value注解需要注意的問(wèn)題

    spring中@value注解需要注意的問(wèn)題

    本篇文章主要介紹了spring中@value注解需要注意的問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • Spring Boot攔截器實(shí)現(xiàn)步驟及測(cè)試實(shí)例

    Spring Boot攔截器實(shí)現(xiàn)步驟及測(cè)試實(shí)例

    這篇文章主要介紹了Spring Boot攔截器實(shí)現(xiàn)步驟及測(cè)試實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Struts2 Result 返回JSON對(duì)象詳解

    Struts2 Result 返回JSON對(duì)象詳解

    這篇文章主要講解Struts2返回JSON對(duì)象的兩種方式,講的比較詳細(xì),希望能給大家做一個(gè)參考。
    2016-06-06
  • java分頁(yè)攔截類實(shí)現(xiàn)sql自動(dòng)分頁(yè)

    java分頁(yè)攔截類實(shí)現(xiàn)sql自動(dòng)分頁(yè)

    這篇文章主要為大家詳細(xì)介紹了java分頁(yè)攔截類可以實(shí)現(xiàn)sql自動(dòng)分頁(yè),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Java多線程編程實(shí)戰(zhàn)之模擬大量數(shù)據(jù)同步

    Java多線程編程實(shí)戰(zhàn)之模擬大量數(shù)據(jù)同步

    這篇文章主要介紹了Java多線程編程實(shí)戰(zhàn)之模擬大量數(shù)據(jù)同步,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • JavaAgent原理及實(shí)踐分享

    JavaAgent原理及實(shí)踐分享

    這篇文章主要介紹了JavaAgent原理及實(shí)踐,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Spring Boot如何使用EhCache演示

    Spring Boot如何使用EhCache演示

    這篇文章主要介紹了Spring Boot如何使用EhCache演示,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java中實(shí)現(xiàn)定時(shí)任務(wù)的兩種方法舉例詳解

    Java中實(shí)現(xiàn)定時(shí)任務(wù)的兩種方法舉例詳解

    這篇文章主要給大家介紹了關(guān)于Java中實(shí)現(xiàn)定時(shí)任務(wù)的兩種方法,文中總結(jié)了各種實(shí)現(xiàn)方式的優(yōu)缺點(diǎn),并給出了推薦的使用場(chǎng)景,通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12
  • Java中BigDecimal的基本運(yùn)算(詳解)

    Java中BigDecimal的基本運(yùn)算(詳解)

    下面小編就為大家?guī)?lái)一篇Java中BigDecimal的基本運(yùn)算(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10

最新評(píng)論