日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

ArrayList類源碼分析

系統(tǒng) 2028 0

ArrayList源碼分析 ?

?? ArrayList是以數(shù)組為基礎(chǔ)實(shí)現(xiàn)的一個(gè)動(dòng)態(tài)數(shù)組容器,通過(guò)以下的代碼分析可知,一方面在ArrayList中添加或者刪除元素(除了在數(shù)組容器末尾添加或者刪除元素),是需要移動(dòng)大量元素的借助System.arraycopy()來(lái)實(shí)現(xiàn)拷貝移動(dòng),另一方面,由于數(shù)組實(shí)現(xiàn)基礎(chǔ),可依靠數(shù)組下標(biāo),可以實(shí)現(xiàn)隨機(jī)訪問(wèn),當(dāng)然查找具體的元素,還是需要循環(huán)去查找的,再者ArrayList不是thread-safe的,在代碼中無(wú)論是add,remove,get,都沒(méi)有任何同步措施,在多線程環(huán)境下需要自己確保thread-safe。由此可知ArrayList適用于在任意位置添加,刪除元素不多,要求隨機(jī)訪問(wèn)的應(yīng)用場(chǎng)景。 ?

? 代碼分析主要羅列:ArrayList構(gòu)造函數(shù),remove(), add(), get() ?

1.ArrayList構(gòu)造函數(shù) ?

?? private transient E[] elementData;ArrayList使用對(duì)象數(shù)組元素來(lái)作為內(nèi)部實(shí)現(xiàn)的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)。 ?

Java代碼 ? ?
  1. //ArrayList是以數(shù)組為基礎(chǔ)實(shí)現(xiàn)的,采用的泛型編程,數(shù)組元素都是Object類型 ??
  2. //初始化時(shí)主要是構(gòu)造指定大小的數(shù)組,用于存儲(chǔ)對(duì)象元素 ??
  3. public ?ArrayList( int ?initialCapacity){??
  4. ?????? super ();??
  5. ?????? if ?(initialCapacity?<? 0 )??
  6. ?????????? throw ? new ?IllegalArgumentException( "Illegal?Capacity:?" +??
  7. ?????????????????????????????????????????????initialCapacity);??
  8. ?????? this .elementData?=?(E[]) new ?Object[initialCapacity];??
  9. }??
Java代碼 ? ? 收藏代碼
  1. //ArrayList是以數(shù)組為基礎(chǔ)實(shí)現(xiàn)的,采用的泛型編程,數(shù)組元素都是Object類型 ??
  2. //初始化時(shí)主要是構(gòu)造指定大小的數(shù)組,用于存儲(chǔ)對(duì)象元素 ??
  3. public ?ArrayList( int ?initialCapacity){??
  4. ?????? super ();??
  5. ?????? if ?(initialCapacity?<? 0 )??
  6. ?????????? throw ? new ?IllegalArgumentException( "Illegal?Capacity:?" +??
  7. ?????????????????????????????????????????????initialCapacity);??
  8. ?????? this .elementData?=?(E[]) new ?Object[initialCapacity];??
  9. }??



?

Java代碼 ? ?
  1. //默認(rèn)情況下ArrayList實(shí)現(xiàn)依賴的數(shù)組長(zhǎng)度為10 ??
  2. ??? public ?ArrayList()?{??
  3. ???????? this ( 10 );??
  4. ???}??
Java代碼 ? ? 收藏代碼
  1. //默認(rèn)情況下ArrayList實(shí)現(xiàn)依賴的數(shù)組長(zhǎng)度為10 ??
  2. ??? public ?ArrayList()?{??
  3. ???????? this ( 10 );??
  4. ???}??


?? ?

?

Java代碼 ? ?
  1. //使用另一個(gè)集合中的元素來(lái)初始化當(dāng)前的List ??
  2. ? public ?ArrayList(Collection<?? extends ?E>?c)?{??
  3. ??????size?=?c.size();??
  4. ?????? //?Allow?10%?room?for?growth ??
  5. ??????elementData?=?(E[]) new ?Object[??
  6. ????????????????????( int )Math.min((size*110L)/ 100 ,Integer.MAX_VALUE)];???
  7. ??????c.toArray(elementData);??
  8. ??}??
Java代碼 ? ? 收藏代碼
  1. //使用另一個(gè)集合中的元素來(lái)初始化當(dāng)前的List ??
  2. ? public ?ArrayList(Collection<?? extends ?E>?c)?{??
  3. ??????size?=?c.size();??
  4. ?????? //?Allow?10%?room?for?growth ??
  5. ??????elementData?=?(E[]) new ?Object[??
  6. ????????????????????( int )Math.min((size*110L)/ 100 ,Integer.MAX_VALUE)];???
  7. ??????c.toArray(elementData);??
  8. ??}??




2. ensureCapaciyt(int) | add(E) | add(int, E)分析 ?

?? ensureCapacity主要用來(lái)實(shí)現(xiàn)數(shù)組的動(dòng)態(tài)擴(kuò)容,每次擴(kuò)容為原來(lái)大小的1.5倍,在add操作前調(diào)用,以確保數(shù)組容量夠用。 ?

Java代碼 ? ?
  1. public ? void ?ensureCapacity( int ?minCapacity)?{??
  2. ??
  3. ????modCount++;??
  4. ???? int ?oldCapacity?=?elementData.length;??
  5. ??????????
  6. ???????? //如果當(dāng)前數(shù)組的實(shí)際容量(oldCapacity)比當(dāng)前要求的容量要小(minCapacity) ??
  7. ???????? //就需要進(jìn)行擴(kuò)容,申請(qǐng)新的數(shù)組空間,大小為minCapacity,并將原來(lái)數(shù)組空間中的元素拷貝 ??
  8. ???????? //到新的數(shù)組空間當(dāng)中。???????? ??
  9. ???? if ?(minCapacity?>?oldCapacity)?{??
  10. ????????Object?oldData[]?=?elementData;??
  11. ????????????
  12. ???????????? //擴(kuò)容因子為:1.5倍左右,每次需要擴(kuò)容時(shí),會(huì)將空間擴(kuò)展為原來(lái)的1.5倍大小 ??
  13. ???????? int ?newCapacity?=?(oldCapacity?*? 3 )/ 2 ?+? 1 ;??
  14. ??
  15. ???????????? if ?(newCapacity?<?minCapacity)??
  16. ????????newCapacity?=?minCapacity;??
  17. ??
  18. ????????elementData?=?(E[]) new ?Object[newCapacity];??
  19. ????????????????
  20. ???????????? //將數(shù)組元素轉(zhuǎn)移到新申請(qǐng)的數(shù)組空間當(dāng)中 ??
  21. ????????System.arraycopy(oldData,? 0 ,?elementData,? 0 ,?size);??
  22. ????}??
  23. }??
Java代碼 ? ? 收藏代碼
  1. public ? void ?ensureCapacity( int ?minCapacity)?{??
  2. ??
  3. ????modCount++;??
  4. ???? int ?oldCapacity?=?elementData.length;??
  5. ??????????
  6. ???????? //如果當(dāng)前數(shù)組的實(shí)際容量(oldCapacity)比當(dāng)前要求的容量要小(minCapacity) ??
  7. ???????? //就需要進(jìn)行擴(kuò)容,申請(qǐng)新的數(shù)組空間,大小為minCapacity,并將原來(lái)數(shù)組空間中的元素拷貝 ??
  8. ???????? //到新的數(shù)組空間當(dāng)中。???????? ??
  9. ???? if ?(minCapacity?>?oldCapacity)?{??
  10. ????????Object?oldData[]?=?elementData;??
  11. ????????????
  12. ???????????? //擴(kuò)容因子為:1.5倍左右,每次需要擴(kuò)容時(shí),會(huì)將空間擴(kuò)展為原來(lái)的1.5倍大小 ??
  13. ???????? int ?newCapacity?=?(oldCapacity?*? 3 )/ 2 ?+? 1 ;??
  14. ??
  15. ???????????? if ?(newCapacity?<?minCapacity)??
  16. ????????newCapacity?=?minCapacity;??
  17. ??
  18. ????????elementData?=?(E[]) new ?Object[newCapacity];??
  19. ????????????????
  20. ???????????? //將數(shù)組元素轉(zhuǎn)移到新申請(qǐng)的數(shù)組空間當(dāng)中 ??
  21. ????????System.arraycopy(oldData,? 0 ,?elementData,? 0 ,?size);??
  22. ????}??
  23. }??



? add(E)操作是向集合ArrayList中存儲(chǔ)元素,在當(dāng)前數(shù)組容器的尾部添加,不需要移動(dòng)元素,返回true。 ?

Java代碼 ? ?
  1. public ? boolean ?add(E?o)?{??
  2. ???????? //調(diào)用ensureCapacity確保當(dāng)前容量不小于(size?+?1),size為容器中當(dāng)前存儲(chǔ)的實(shí)際元素個(gè)數(shù). ??
  3. ????ensureCapacity(size?+? 1 );???
  4. ???????? //將對(duì)象引用o保存到數(shù)組容器中,并++size. ??
  5. ????elementData[size++]?=?o;??
  6. ???? return ? true ;??
  7. }??
Java代碼 ? ? 收藏代碼
  1. public ? boolean ?add(E?o)?{??
  2. ???????? //調(diào)用ensureCapacity確保當(dāng)前容量不小于(size?+?1),size為容器中當(dāng)前存儲(chǔ)的實(shí)際元素個(gè)數(shù). ??
  3. ????ensureCapacity(size?+? 1 );???
  4. ???????? //將對(duì)象引用o保存到數(shù)組容器中,并++size. ??
  5. ????elementData[size++]?=?o;??
  6. ???? return ? true ;??
  7. }??



add(int , E)在ArrayList中的指定位置index,保存對(duì)象element. ?

Java代碼 ? ?
  1. public ? void ?add( int ?index,?E?element)?{??
  2. ??
  3. ???????? //檢測(cè)指定位置的合法性 ??
  4. ???? if ?(index?>?size?||?index?<? 0 )??
  5. ???????? throw ? new ?IndexOutOfBoundsException(??
  6. ???????? "Index:?" +index+ ",?Size:?" +size);??
  7. ??
  8. ????ensureCapacity(size+ 1 );??
  9. ??????????
  10. ???????? //將數(shù)組容器elementData中從index位置開(kāi)始的元素,依次往后移動(dòng)一個(gè)位置 ??
  11. ???????? //也就是說(shuō)經(jīng)過(guò)arraycopy()后,index位置被空出來(lái) ??
  12. ????System.arraycopy(elementData,?index,?elementData,?index?+? 1 ,??
  13. ?????????????size?-?index);??
  14. ??
  15. ???????? //將對(duì)象element存儲(chǔ)到數(shù)組容器的index位置上 ??
  16. ????elementData[index]?=?element;??
  17. ????size++;??
  18. }??
Java代碼 ? ? 收藏代碼
  1. public ? void ?add( int ?index,?E?element)?{??
  2. ??
  3. ???????? //檢測(cè)指定位置的合法性 ??
  4. ???? if ?(index?>?size?||?index?<? 0 )??
  5. ???????? throw ? new ?IndexOutOfBoundsException(??
  6. ???????? "Index:?" +index+ ",?Size:?" +size);??
  7. ??
  8. ????ensureCapacity(size+ 1 );??
  9. ??????????
  10. ???????? //將數(shù)組容器elementData中從index位置開(kāi)始的元素,依次往后移動(dòng)一個(gè)位置 ??
  11. ???????? //也就是說(shuō)經(jīng)過(guò)arraycopy()后,index位置被空出來(lái) ??
  12. ????System.arraycopy(elementData,?index,?elementData,?index?+? 1 ,??
  13. ?????????????size?-?index);??
  14. ??
  15. ???????? //將對(duì)象element存儲(chǔ)到數(shù)組容器的index位置上 ??
  16. ????elementData[index]?=?element;??
  17. ????size++;??
  18. }??





3. remove(int) | remove(Object) | fastRemove(int) | removeRange(int,int)分析 ?

? remove(int)用于刪除ArrayList數(shù)組容器中指定位置int上的元素,并返回此元素. ?

Java代碼 ? ?
  1. public ?E?remove( int ?index)?{??
  2. ??
  3. ????RangeCheck(index);??
  4. ??
  5. ????modCount++;??
  6. ??
  7. ????E?oldValue?=?elementData[index];??
  8. ???????? //numMoved需要移動(dòng)的元素個(gè)數(shù),也就是index后面的所有的元素個(gè)數(shù) ??
  9. ???? int ?numMoved?=?size?-?index?-? 1 ;??
  10. ??
  11. ???????? //將index后面的所有元素全部往前依次移動(dòng)一個(gè)位置 ??
  12. ???? if ?(numMoved?>? 0 )??
  13. ????????System.arraycopy(elementData,?index+ 1 ,?elementData,?index,??
  14. ?????????????????numMoved);??
  15. ??
  16. ???????? //經(jīng)過(guò)arraycopy的移位,數(shù)組容器的最個(gè)位置被騰空, ??
  17. ???????? //但是仍然持有某個(gè)對(duì)象的引用,需要把這個(gè)多余的引用置為null. ??
  18. ????????elementData[--size]?=? null ;? //?Let?gc?do?its?work ??
  19. ??
  20. ???? return ?oldValue;??
  21. }??
Java代碼 ? ? 收藏代碼
  1. public ?E?remove( int ?index)?{??
  2. ??
  3. ????RangeCheck(index);??
  4. ??
  5. ????modCount++;??
  6. ??
  7. ????E?oldValue?=?elementData[index];??
  8. ???????? //numMoved需要移動(dòng)的元素個(gè)數(shù),也就是index后面的所有的元素個(gè)數(shù) ??
  9. ???? int ?numMoved?=?size?-?index?-? 1 ;??
  10. ??
  11. ???????? //將index后面的所有元素全部往前依次移動(dòng)一個(gè)位置 ??
  12. ???? if ?(numMoved?>? 0 )??
  13. ????????System.arraycopy(elementData,?index+ 1 ,?elementData,?index,??
  14. ?????????????????numMoved);??
  15. ??
  16. ???????? //經(jīng)過(guò)arraycopy的移位,數(shù)組容器的最個(gè)位置被騰空, ??
  17. ???????? //但是仍然持有某個(gè)對(duì)象的引用,需要把這個(gè)多余的引用置為null. ??
  18. ????????elementData[--size]?=? null ;? //?Let?gc?do?its?work ??
  19. ??
  20. ???? return ?oldValue;??
  21. }??


remove(Object)刪除指定的對(duì)象Object,在數(shù)組容器中,需要特別處理null對(duì)象,過(guò)程都是,首先在數(shù)組容器中循環(huán)查找某個(gè)對(duì)象,如果查找到則調(diào)用fastRemove()進(jìn)行刪除。 ?

Java代碼 ? ?
  1. public ? boolean ?remove(Object?o)?{??
  2. ???? if ?(o?==? null )?{??
  3. ???????????? for ?( int ?index?=? 0 ;?index?<?size;?index++)??
  4. ???????? if ?(elementData[index]?==? null )?{??
  5. ????????????fastRemove(index);??
  6. ???????????? return ? true ;??
  7. ????????}??
  8. ????}? else ?{??
  9. ???????????? //注意比較兩個(gè)對(duì)象是否相等調(diào)用的是equals(), ??
  10. ???????????? //如果此類對(duì)象沒(méi)有重寫(xiě)equals() ??
  11. ???????????? //比較的是是否引用同一個(gè)對(duì)象,如果有重寫(xiě),將比較對(duì)象內(nèi)部狀態(tài). ??
  12. ???????? for ?( int ?index?=? 0 ;?index?<?size;?index++)??
  13. ???????? if ?(o.equals(elementData[index]))?{??
  14. ????????????fastRemove(index);??
  15. ???????????? return ? true ;??
  16. ????????}??
  17. ????????}??
  18. ???? return ? false ;??
  19. ????}??
Java代碼 ? ? 收藏代碼
  1. public ? boolean ?remove(Object?o)?{??
  2. ???? if ?(o?==? null )?{??
  3. ???????????? for ?( int ?index?=? 0 ;?index?<?size;?index++)??
  4. ???????? if ?(elementData[index]?==? null )?{??
  5. ????????????fastRemove(index);??
  6. ???????????? return ? true ;??
  7. ????????}??
  8. ????}? else ?{??
  9. ???????????? //注意比較兩個(gè)對(duì)象是否相等調(diào)用的是equals(), ??
  10. ???????????? //如果此類對(duì)象沒(méi)有重寫(xiě)equals() ??
  11. ???????????? //比較的是是否引用同一個(gè)對(duì)象,如果有重寫(xiě),將比較對(duì)象內(nèi)部狀態(tài). ??
  12. ???????? for ?( int ?index?=? 0 ;?index?<?size;?index++)??
  13. ???????? if ?(o.equals(elementData[index]))?{??
  14. ????????????fastRemove(index);??
  15. ???????????? return ? true ;??
  16. ????????}??
  17. ????????}??
  18. ???? return ? false ;??
  19. ????}??



fastRemove(int index)是相對(duì)于remove(int index)來(lái)說(shuō)的,因?yàn)椴恍枰M(jìn)行index合法性檢查和返回被刪除的元素,所以它可以稱為fast remove.fastRemove是private不能被外界訪問(wèn),只是在remove(Object o)中被調(diào)用,因?yàn)閞emove(Object o)在調(diào)用fastRemove()時(shí)候已經(jīng)確定了此對(duì)象的確存在才進(jìn)行fastRemove(),所以是安全的,不需要檢查。 ?

Java代碼 ? ?
  1. private ? void ?fastRemove( int ?index)?{??
  2. ???????modCount++;??
  3. ??????? int ?numMoved?=?size?-?index?-? 1 ;??
  4. ??????? if ?(numMoved?>? 0 )??
  5. ???????????System.arraycopy(elementData,?index+ 1 ,?elementData,?index,???
  6. ????????????????????????????numMoved);??
  7. ???????elementData[--size]?=? null ;? //?Let?gc?do?its?work ??
  8. ?}??
Java代碼 ? ? 收藏代碼
  1. private ? void ?fastRemove( int ?index)?{??
  2. ???????modCount++;??
  3. ??????? int ?numMoved?=?size?-?index?-? 1 ;??
  4. ??????? if ?(numMoved?>? 0 )??
  5. ???????????System.arraycopy(elementData,?index+ 1 ,?elementData,?index,???
  6. ????????????????????????????numMoved);??
  7. ???????elementData[--size]?=? null ;? //?Let?gc?do?its?work ??
  8. ?}??




removeRange(int, int)用于刪除數(shù)組容器中指定下標(biāo)范圍內(nèi)的元素 ?

Java代碼 ? ?
  1. ??? protected ? void ?removeRange( int ?fromIndex,? int ?toIndex)?{??
  2. modCount++;??
  3. int ?numMoved?=?size?-?toIndex;??
  4. ??????? //將從toIndex開(kāi)始的元素依次拷貝到fromIndex位置上。 ??
  5. ???????System.arraycopy(elementData,?toIndex,?elementData,?fromIndex,??
  6. ????????????????????????numMoved);??
  7. ??
  8. //?Let?gc?do?its?work ??
  9. ??????? //newSize為刪除指定范圍元素后,容器中所剩下的元素個(gè)數(shù)。 ??
  10. int ?newSize?=?size?-?(toIndex-fromIndex);??
  11. ??????? //將持有多余引用的元素位置(從size-1到newSize?-?1)置為null, ??
  12. ??????? //讓GC能夠及時(shí)回收垃圾對(duì)象. ??
  13. while ?(size?!=?newSize)??
  14. ????elementData[--size]?=? null ;??
  15. ???}??
Java代碼 ? ? 收藏代碼
  1. ??? protected ? void ?removeRange( int ?fromIndex,? int ?toIndex)?{??
  2. modCount++;??
  3. int ?numMoved?=?size?-?toIndex;??
  4. ??????? //將從toIndex開(kāi)始的元素依次拷貝到fromIndex位置上。 ??
  5. ???????System.arraycopy(elementData,?toIndex,?elementData,?fromIndex,??
  6. ????????????????????????numMoved);??
  7. ??
  8. //?Let?gc?do?its?work ??
  9. ??????? //newSize為刪除指定范圍元素后,容器中所剩下的元素個(gè)數(shù)。 ??
  10. int ?newSize?=?size?-?(toIndex-fromIndex);??
  11. ??????? //將持有多余引用的元素位置(從size-1到newSize?-?1)置為null, ??
  12. ??????? //讓GC能夠及時(shí)回收垃圾對(duì)象. ??
  13. while ?(size?!=?newSize)??
  14. ????elementData[--size]?=? null ;??
  15. ???}??



4. get(int) ?

get(int)用于獲取ArrayList指定位置的元素,就是從數(shù)組中指定位置上取元素。 ?

Java代碼 ? ?
  1. public ?E?get( int ?index)?{??
  2. ??
  3. ???????? //RangeCheck(index)用于檢查index在數(shù)組元素中位置是否合法(必須index?<?size) ??
  4. ????RangeCheck(index);??
  5. ??
  6. ???? return ?elementData[index];??
  7. }??
Java代碼 ? ? 收藏代碼
  1. public ?E?get( int ?index)?{??
  2. ??
  3. ???????? //RangeCheck(index)用于檢查index在數(shù)組元素中位置是否合法(必須index?<?size) ??
  4. ????RangeCheck(index);??
  5. ??
  6. ???? return ?elementData[index];??
  7. }??

ArrayList類源碼分析


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 内乡县| 大厂| 吉安市| 武安市| 卢龙县| 山西省| 余姚市| 巴彦县| 瓦房店市| 抚松县| 南宁市| 翁源县| 剑河县| 仙桃市| 成武县| 嘉鱼县| 德惠市| 武隆县| 定西市| 芦山县| 广灵县| 鲁山县| 曲水县| 长泰县| 墨竹工卡县| 乐都县| 杭锦后旗| 肇东市| 曲水县| 阿拉尔市| 海林市| 桃园市| 山西省| 尉犁县| 吐鲁番市| 莎车县| 隆子县| 自贡市| 平和县| 出国| 常宁市|