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

在java中ArrayList集合底層的擴(kuò)容原理

 更新時(shí)間:2021年04月14日 16:02:27   作者:浪客川  
這篇文章主要介紹了在java中ArrayList集合底層的擴(kuò)容原理,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有一定的幫助,需要的朋友可以參考下

第一章 前言概述

第01節(jié) 概述

底層說(shuō)明

ArrayList是List的實(shí)現(xiàn)類,它的底層是用Object數(shù)組存儲(chǔ),線程不安全

后期應(yīng)用

適合用于頻繁的查詢工作,因?yàn)榈讓邮菙?shù)組,可以快速通過(guò)數(shù)組下標(biāo)進(jìn)行查找

第02節(jié) 區(qū)別

區(qū)別方向 ArrayList集合 LinkedList集合
線程安全 不安全 不安全
底層原理 Object類型數(shù)組 雙向鏈表
隨機(jī)訪問(wèn) 支持(實(shí)現(xiàn) RandomAccess接口) 不支持
內(nèi)存占用 ArrayList 浪費(fèi)空間, 底層是數(shù)組,末尾預(yù)留一部分容量空間 LinkedList占用空間比ArrayList多,存在頭尾地址值占用空間

小結(jié)

ArrayList 集合的特點(diǎn):

1. 線程不安全

2. 底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組(查詢快,增刪慢,支持快速隨機(jī)訪問(wèn))

3. 內(nèi)存占用會(huì)存在部分浪費(fèi),末尾會(huì)預(yù)留一部分容量空間

第二章 核心代碼

第01節(jié) 成員變量

代碼

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ 

	/**
	 * 默認(rèn)初始容量大小, 默認(rèn)初始化容量為10
	 */
	private static final int DEFAULT_CAPACITY = 10;

	/**
	 * 空數(shù)組。當(dāng)集合內(nèi)容置空的時(shí)候,底層使用空數(shù)組標(biāo)記
	 */
	private static final Object[] EMPTY_ELEMENTDATA = {};

	/**
	* 用于無(wú)參數(shù)構(gòu)造方法,創(chuàng)建對(duì)象的時(shí)候,使用這個(gè)數(shù)組定義。
	* 相比上面的數(shù)組 EMPTY_ELEMENTDATA 可以進(jìn)行區(qū)分,知道在添加元素的過(guò)程當(dāng)中,容量增加多少
	*/
	private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

	/**
	 * 保存ArrayList數(shù)據(jù)的數(shù)組,這個(gè)數(shù)組會(huì)不斷的改變,前面沒(méi)有被 final 修飾表示地址值會(huì)發(fā)生的變化
	 */
	transient Object[] elementData; // non-private to simplify nested class access

	/**
	 * ArrayList 所包含的元素個(gè)數(shù),也就是在 ArrayList 集合底層,通過(guò) size()方法,獲取到的元素個(gè)數(shù)
	 */
	private int size; 
}

補(bǔ)充

1. ArrayList 集合底層存在6個(gè)成員變量
	還有一個(gè) private static final long serialVersionUID = 8683452581122892189L;  
	序列化使用, 目前針對(duì)于當(dāng)前的操作過(guò)程當(dāng)中, 暫時(shí)不會(huì)使用得到。

2. ArrayList 集合當(dāng)中核心的兩個(gè)成員變量
	A. 底層維護(hù)數(shù)組  		transient Object[] elementData;
	B. 存儲(chǔ)的元素個(gè)數(shù)		private int size; 

第02節(jié) 構(gòu)造方法

代碼

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ 

    /**
     * 構(gòu)造一個(gè)初始長(zhǎng)度為0的空數(shù)組。
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    /**
     * 在構(gòu)造方法當(dāng)中,傳遞一個(gè)參數(shù)集合c,將集合 c 轉(zhuǎn)換成為新的列表
	 * elementData 當(dāng)中的數(shù)據(jù),就是新集合存放的數(shù)據(jù)
     * c.toArray 就是將原始集合的數(shù)據(jù)取出
	 * 如果取出的集合長(zhǎng)度不為零的情況下,則復(fù)制 參數(shù)集合c 到 elementData 當(dāng)中
	 * 如果取出的集合長(zhǎng)度為零的情況下,則賦值為空數(shù)組  EMPTY_ELEMENTDATA 
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) { 
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else { 
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
	
	 /**
     * 指定參數(shù)的長(zhǎng)度大小
	 * 如果初始化的長(zhǎng)度大于0,則返回新的數(shù)組
	 * 如果初始化的長(zhǎng)度等于0,則返回默認(rèn)的空數(shù)組作為集合 this.elementData = EMPTY_ELEMENTDATA;
	 * 如果初始化的長(zhǎng)度小于0,則出現(xiàn)非法參數(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);
        }
    }
}

補(bǔ)充(一) 無(wú)參構(gòu)造創(chuàng)建對(duì)象

在這里插入圖片描述

補(bǔ)充(二)帶參構(gòu)造創(chuàng)建對(duì)象,帶有int類型參數(shù)

在這里插入圖片描述

補(bǔ)充(三)帶參構(gòu)造創(chuàng)建對(duì)象,帶有 集合類型參數(shù)

在這里插入圖片描述

第三章 擴(kuò)容操作

第01節(jié) 擴(kuò)容代碼

核心方法介紹

來(lái)自于 ArrayList 集合當(dāng)中的方法:
	1. public boolean add(E e){ ... }
	2. private void add(E e, Object[] elementData, int s){ .... }
	3. private Object[] grow()
	4. private Object[] grow(int minCapacity)

來(lái)自于其他類當(dāng)中的功能
	1. Arrays.copyOf(elementData, newCapacity);  表示來(lái)自于 數(shù)組工具類 Arrays 當(dāng)中的 copyOf() 底層使用的是 System.arraycopy() 方法
	2. Math.max(DEFAULT_CAPACITY, minCapacity)   表示來(lái)自于 數(shù)學(xué)工具類 Math 當(dāng)中的 max() 方法,比較兩個(gè)數(shù)據(jù)最大值,取較大者,返回

核心代碼解釋

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ 

    /**
     * 將指定的元素添加到此集合的末尾位置
     *
     * modCount 是來(lái)自于父類的 AbstractList 當(dāng)中的成員變量
     * add(e, elementData, size) 調(diào)用自己下面的重載方法
	 * return true  表示當(dāng)前的方法,一定可以添加成功,因?yàn)長(zhǎng)ist系列的集合添加數(shù)據(jù)都是允許成功的 true 如果是Set此方法返回false
     */
    public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }
	
	
	/**
     * 這個(gè)方法是私有方法,僅僅自己可以使用。不允許外界訪問(wèn)得到。便于上面的 add() 方法重載調(diào)用的
	 * 參數(shù)1: 表示需要添加的元素?cái)?shù)據(jù) E e
	 * 參數(shù)2: 表示成員變量當(dāng)中, 需要維護(hù)管理的底層數(shù)組  Object[] elementData
     * 參數(shù)3: 表示成員變量當(dāng)中, size 容器 elementData 當(dāng)中存放的真實(shí)有效的數(shù)據(jù)個(gè)數(shù)
	 * 方法里面的邏輯: 當(dāng)size已經(jīng)等于了內(nèi)部容器 elementData 的最大長(zhǎng)度,則準(zhǔn)備進(jìn)行擴(kuò)容的操作,擴(kuò)容使用 grow() 方法
	 * 無(wú)論上面是否進(jìn)行了擴(kuò)容的操作,這里都需要將添加的元素賦值到數(shù)組當(dāng)中,也就是 elementData[s] = e;
	 * 并且將當(dāng)前成員變量的 size 在原始數(shù)據(jù)的基礎(chǔ)上面,增加1,表示添加了新的元素之后,長(zhǎng)度變化了,增加了1
     */
    private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        size = s + 1;
    }
	
	
	/**
     * 這個(gè)方法是私有方法,僅僅自己可以使用。不允許外界訪問(wèn)得到。便于上面的 add() 方法調(diào)用的
	 * 方法的內(nèi)部調(diào)用了 ArrayList 當(dāng)中自己重載的方法 grow(size + 1) 同時(shí)傳入了參數(shù)。
	 * 這里參數(shù)的含義,表示的是 集合當(dāng)中總長(zhǎng)度 size + 1 表示在原始size基礎(chǔ)上增加1 
	 * 方法的返回值是一個(gè)新的數(shù)組,也就是擴(kuò)容之后的數(shù)組
     */
	private Object[] grow() {
        return grow(size + 1);
    }


    /**
     * 這個(gè)方法是私有方法,僅僅自己可以使用。不允許外界訪問(wèn)得到。便于上面的 grow() 方法調(diào)用的
	 * 這里的參數(shù) minCapacity ,就是上面?zhèn)魅氲膮?shù) size + 1,也就是說(shuō)最小容量 minCapacity = size + 1
	 * 方法體當(dāng)中的執(zhí)行邏輯:
	 * 		1. 獲取到了底層維護(hù)數(shù)組的長(zhǎng)度 int oldCapacity = elementData.length; 這里就是舊容量 oldCapacity
	 *      2. 判斷舊容量 oldCapacity 是否小于0,也就是 else 的邏輯,
	 *				如果滿足 if 當(dāng)中的邏輯, 則表示 舊數(shù)組當(dāng)中存在數(shù)據(jù),并且 舊數(shù)組并不是 默認(rèn)容量的空數(shù)組地址值
	 *					說(shuō)明: 擴(kuò)容過(guò)的就不會(huì)是之前默認(rèn) DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的地址值
	 *					在這種情況下,就會(huì)得到 1.5被的數(shù)組長(zhǎng)度整數(shù),傳遞給 Arrays.copyOf()方法進(jìn)行擴(kuò)容,得到新數(shù)組返回
	 * 				如果滿足 else 當(dāng)中的邏輯,則返回 DEFAULT_CAPACITY 和 minCapacity 較大值。
	 * 					說(shuō)明: DEFAULT_CAPACITY 值表示的是成員變量,默認(rèn)為 10   
	 *					說(shuō)明: minCapacity 在低于10的時(shí)候,表示的會(huì)是擴(kuò)容添加的長(zhǎng)度1,2,3..9.10.11..
     */
    private Object[] grow(int minCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            int newCapacity = ArraysSupport.newLength(oldCapacity,
                    minCapacity - oldCapacity, /* minimum growth */
                    oldCapacity >> 1           /* preferred growth */);
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }
}

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

相關(guān)文章

  • Java金額大小寫的轉(zhuǎn)換方法

    Java金額大小寫的轉(zhuǎn)換方法

    這篇文章主要為大家詳細(xì)介紹了Java金額大小寫的轉(zhuǎn)換方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java單例模式簡(jiǎn)單示例

    Java單例模式簡(jiǎn)單示例

    這篇文章主要介紹了Java單例模式,結(jié)合實(shí)例形式簡(jiǎn)單分析了java單例模式的定義與使用技巧,需要的朋友可以參考下
    2017-06-06
  • Springboot GET和POST請(qǐng)求參數(shù)獲取方式小結(jié)

    Springboot GET和POST請(qǐng)求參數(shù)獲取方式小結(jié)

    Spring Boot GET和POST請(qǐng)求參數(shù)獲取是開(kāi)發(fā)人員經(jīng)常需要解決的問(wèn)題,本文主要介紹了Springboot GET和POST請(qǐng)求參數(shù)獲取方式小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • 如何對(duì)quartz定時(shí)任務(wù)設(shè)置結(jié)束時(shí)間

    如何對(duì)quartz定時(shí)任務(wù)設(shè)置結(jié)束時(shí)間

    這篇文章主要介紹了如何對(duì)quartz定時(shí)任務(wù)設(shè)置結(jié)束時(shí)間問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • IDEA如何修改項(xiàng)目名稱出現(xiàn)中括號(hào)

    IDEA如何修改項(xiàng)目名稱出現(xiàn)中括號(hào)

    當(dāng)項(xiàng)目文件夾名稱與model名稱不一致時(shí),IDEA會(huì)在項(xiàng)目名旁顯示中括號(hào)以區(qū)分,修改項(xiàng)目名稱時(shí)出現(xiàn)中括號(hào)問(wèn)題,通常是因?yàn)镮DE中model名與文件夾名不同步,解決方法是統(tǒng)一model名稱和文件夾名稱,可通過(guò)重構(gòu)功能或項(xiàng)目結(jié)構(gòu)設(shè)置完成,重命名操作應(yīng)謹(jǐn)慎,以避免路徑等引用錯(cuò)誤
    2024-10-10
  • 基于mybatis注解動(dòng)態(tài)sql中foreach工具的方法

    基于mybatis注解動(dòng)態(tài)sql中foreach工具的方法

    這篇文章主要介紹了mybatis注解動(dòng)態(tài)sql中foreach工具方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java如何在不存在文件夾的目錄下創(chuàng)建文件

    Java如何在不存在文件夾的目錄下創(chuàng)建文件

    這篇文章主要介紹了Java如何在不存在文件夾的目錄下創(chuàng)建文件,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-08-08
  • Map與JavaBean相互轉(zhuǎn)換的工具類?

    Map與JavaBean相互轉(zhuǎn)換的工具類?

    這篇文章主要介紹了Map與JavaBean相互轉(zhuǎn)換的工具類,在做導(dǎo)入的時(shí)候,遇到了需要將map對(duì)象轉(zhuǎn)化?成javabean的問(wèn)題,也就是說(shuō),不清楚javabean的內(nèi)部字段排列,只知道m(xù)ap的?key代表javabean的字段名,value代表值,需要的朋友可以參考下
    2022-02-02
  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(16)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(16)

    下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你
    2021-07-07
  • springboot應(yīng)用中使用過(guò)濾器的過(guò)程詳解

    springboot應(yīng)用中使用過(guò)濾器的過(guò)程詳解

    過(guò)濾器通常用于實(shí)現(xiàn)跨切面的功能,例如身份驗(yàn)證、日志記錄、請(qǐng)求和響應(yīng)的修改、性能監(jiān)控等,這篇文章主要介紹了springboot應(yīng)用中使用過(guò)濾器,需要的朋友可以參考下
    2023-06-06

最新評(píng)論

会泽县| 新邵县| 扎鲁特旗| 象山县| 乌拉特前旗| 江孜县| 禹城市| 塘沽区| 南皮县| 永吉县| 平塘县| 五常市| 宜城市| 仁怀市| 偏关县| 永新县| 孟津县| 常熟市| 司法| 浦城县| 平湖市| 九台市| 玉门市| 中西区| 江永县| 阜宁县| 福泉市| 奉新县| 鲁甸县| 泊头市| 同德县| 云霄县| 九龙坡区| 冕宁县| 南郑县| 临海市| 遂川县| 鲁甸县| 德昌县| 嘉黎县| 陆川县|