目錄
一、有無初始容量的區(qū)別二、initialCapacity != list.size()總結(jié)平時寫代碼都直接寫
Listlist = new ArrayList<>();
由于公司做政.府項(xiàng)目,對并發(fā)和響應(yīng)沒有太苛刻的要求,平時就沒有考慮到這一塊。
今天看同事代碼在new ArrayList<>()的時候帶入初始容量,于是好奇百度一下,講結(jié)果記錄下來。
(相關(guān)資料圖)
一、有無初始容量的區(qū)別
/** ? ? ?* The maximum size of array to allocate. ? ? ?* Some VMs reserve some header words in an array. ? ? ?* Attempts to allocate larger arrays may result in ? ? ?* OutOfMemoryError: Requested array size exceeds VM limit ? ? ?*/ ? ? private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; ? ?? ?? ?/** ? ? ?* Default initial capacity. ? ? ?*/ ? ? private static final int DEFAULT_CAPACITY = 10; ?? ?/** ? ? ?* The array buffer into which the elements of the ArrayList are stored. ? ? ?* The capacity of the ArrayList is the length of this array buffer. Any ? ? ?* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA ? ? ?* will be expanded to DEFAULT_CAPACITY when the first element is added. ? ? ?*/ ? ? transient Object[] elementData; // non-private to simplify nested class access ?? ?/** ? ? ?* Shared empty array instance used for empty instances. ? ? ?*/ ? ? private static final Object[] EMPTY_ELEMENTDATA = {};?? ? ?? ?/** ? ? ?* Constructs an empty list with the specified initial capacity. ? ? ?* ? ? ?* @param ?initialCapacity ?the initial capacity of the list ? ? ?* @throws IllegalArgumentException if the specified initial capacity ? ? ?* ? ? ? ? is negative ? ? ?*/ ? ? 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); ? ? ? ? } ? ? } ?? ?/** ? ? ?* Increases the capacity to ensure that it can hold at least the ? ? ?* number of elements specified by the minimum capacity argument. ? ? ?* ? ? ?* @param minCapacity the desired minimum capacity ? ? ?*/ ? ? private void grow(int minCapacity) { ? ? ? ? // overflow-conscious code ? ? ? ? int oldCapacity = elementData.length; ? ? ? ? int newCapacity = oldCapacity + (oldCapacity >> 1); ? ? ? ? if (newCapacity - minCapacity < 0) ? ? ? ? ? ? newCapacity = minCapacity; ? ? ? ? if (newCapacity - MAX_ARRAY_SIZE > 0) ? ? ? ? ? ? newCapacity = hugeCapacity(minCapacity); ? ? ? ? // minCapacity is usually close to size, so this is a win: ? ? ? ? elementData = Arrays.copyOf(elementData, newCapacity); ? ? }
以上是JDK1.8的ArrayList源碼,可以看出,
沒有初始容量的話,在做數(shù)據(jù)操作的時候ArrayList會自己創(chuàng)建容量,JDK1.8默認(rèn)為10每次擴(kuò)容后容量為oldCapacity + (oldCapacity >> 1)容量最大值Integer.MAX_VALUE - 8由此可以想到,如果存在上千上萬數(shù)據(jù)量的操作,不初始容量和初始化了合適的容量,處理時間肯定不同,因?yàn)槌跏蓟蛿U(kuò)容是需要時間的。
測試代碼如下:
public static void main(String[] args) { ? ? final int count = 200 * 10000; ? ? Listlist = new ArrayList<>(); ? ? long begin = System.currentTimeMillis(); ? ? for(int i = 0; i < count ; i++) { ? ? ? ? list.add(i); ? ? } ? ? System.out.println("沒有設(shè)置ArrayList初始容量: " + (System.currentTimeMillis() - begin) + " ms"); ? ? List list2 = new ArrayList<>(10); ? ? long begin2 = System.currentTimeMillis(); ? ? for(int i = 0; i < count ; i++) { ? ? ? ? list2.add(i); ? ? } ? ? System.out.println("設(shè)置了ArrayList初始容量: " + (System.currentTimeMillis() - begin2) + " ms"); }
輸出:
沒有設(shè)置ArrayList初始容量: 96 ms
設(shè)置了ArrayList初始容量: 26 ms
分析:
在list.add()方法執(zhí)行時,先調(diào)用ArrayList的:
/** ?* Appends the specified element to the end of this list. ?* ?* @param e element to be appended to this list ?* @return true (as specified by {@link Collection#add}) ?*/ public boolean add(E e) { ? ? ensureCapacityInternal(size + 1); ?// Increments modCount!! ? ? elementData[size++] = e; ? ? return true; }
進(jìn)入方法:
private void ensureCapacityInternal(int minCapacity) { ? ? ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); }
再往下:
private static int calculateCapacity(Object[] elementData, int minCapacity) { ? ? if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {// 第一次add的時候,都會走這一步 ? ? ? ? return Math.max(DEFAULT_CAPACITY, minCapacity);//初始化容量小于默認(rèn)值10都會取10,反之取自定義的容量 ? ? } ? ? return minCapacity; }
擴(kuò)容方法:
private void ensureExplicitCapacity(int minCapacity) { ? ? modCount++; ? ? // overflow-conscious code ? ? if (minCapacity - elementData.length > 0) ? ? ? ? grow(minCapacity); }
grow():
/** ?* Increases the capacity to ensure that it can hold at least the ?* number of elements specified by the minimum capacity argument. ?* ?* @param minCapacity the desired minimum capacity ?*/ ?private void grow(int minCapacity) {//minCapacity是當(dāng)前容量,比如,默認(rèn)容量下,add一次后就是10+1 ? ? // overflow-conscious code ? ? int oldCapacity = elementData.length; ? ? int newCapacity = oldCapacity + (oldCapacity >> 1); ? ? if (newCapacity - minCapacity < 0) ? ? ? ? newCapacity = minCapacity; ? ? if (newCapacity - MAX_ARRAY_SIZE > 0) ? ? ? ? newCapacity = hugeCapacity(minCapacity); ? ? // minCapacity is usually close to size, so this is a win: ? ? elementData = Arrays.copyOf(elementData, newCapacity); }
總結(jié):
建議初始化容量,減少系統(tǒng)初始化容量的耗時;初始化容量不是越大越好,跟系統(tǒng)配置相關(guān),因?yàn)橐_辟內(nèi)存。如果能確定add的總數(shù),以總數(shù)作為初始容量效率最高,但這種場景太少了。最佳的設(shè)置要兼顧內(nèi)存空間和擴(kuò)容次數(shù),我也沒有找到最優(yōu)解,歡迎大佬補(bǔ)充。盡管不知道初始化多少最快,但是初始化比未初始化快,并且有限的數(shù)據(jù)量下,設(shè)置不同initialCapacity的差距不大。最終,我建議大家初始化容量,并且就寫10(<=10都一樣,看自己喜好)。上例不同大小初始容量的耗時:
initialCapacity | time |
---|---|
未初始化 | 96 |
<=10 | 26 |
100 | 26 |
1000 | 23 |
10000 | 648 |
100000 | 24 |
1000000 | 18 |
10000000 | 609 |
二、initialCapacity != list.size()
public static void main(String[] args) { ? ? Listlist = new ArrayList<>(10); ? ? list.set(0, 666); }
console:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(ArrayList.java:657)
at java.util.ArrayList.set(ArrayList.java:448)
at top.chengsw.demo.test.ListTest.main(ListTest.java:25)
此時,list.size() = 0。
也就是說,該構(gòu)造方法并不是將ArrayList()初始化為指定長度,而是指定了其內(nèi)部的Object數(shù)組的長度,也就是其容量。
當(dāng)我們調(diào)用size()時,返回的是其實(shí)際長度,而非容量大小。
對超出ArrayList長度的部分進(jìn)行訪問或賦值操作時也會造成訪問越界,盡管它的容量大小足夠。
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
關(guān)鍵詞:
-
基于ArrayList初始化長度的作用及影響 焦點(diǎn)消息
這篇文章主要介紹了基于ArrayList初始化長度的作用及影響,具有很好的
-
漢蘭達(dá)多重優(yōu)惠拒躺平
近一兩年來,隨著國產(chǎn)汽車特別是國產(chǎn)新能源汽車的快速崛起,傳統(tǒng)合資燃
-
湖人在2023年選秀大會上成為主角,有四筆簽約,令人記憶深刻 天天視訊
洛杉磯湖人在2023年NBA選秀大會當(dāng)天,儼然成為這屆選秀大會的主角。雖
-
全球熱點(diǎn)評!青島雙星蘇明:圍繞三大主業(yè)實(shí)施“新四化”戰(zhàn)略
青島雙星總經(jīng)理蘇明表示,雙星正圍繞橡膠輪胎、人工智能及高端裝備、綠
-
火鍋油碟是什么_油碟是什么
1、油是指液壓盤式制動器,以油為介質(zhì)。剎把內(nèi)部的活塞起到壓縮機(jī)油的
-
中國氣象局啟動高溫四級應(yīng)急響應(yīng) 頭條
中國氣象局各有關(guān)單位在做好暴雨應(yīng)急響應(yīng)的同時,加強(qiáng)值班值守,強(qiáng)化國
-
曾厝垵(關(guān)于曾厝垵介紹)|環(huán)球觀天下
來為大家解答以上的問題。曾厝垵,厝垵介紹這個很多人還不知道,現(xiàn)在讓
-
神印王座:圣靈心被兩大魔神重創(chuàng),龍皓晨一念魔化,圣采兒慌了_全球播報
神印王座第61集預(yù)告已經(jīng)更新了。從官方新出預(yù)告來看,圣靈心和龍皓晨已
-
千年私服視頻_千年私服-今日熱聞
1、希望您做好-------------------------美國服務(wù)器租用----------------美國圣安娜
-
世界最資訊丨西安,中國人的原鄉(xiāng)——吳文莉的“西安城”記憶
【讀書者說】作者:王剛(西安市文學(xué)藝術(shù)創(chuàng)作研究室專業(yè)作家)在當(dāng)代陜
-
爆款預(yù)定?比亞迪三款全新車型待發(fā)布,一個比一個好看_當(dāng)前報道
作為國內(nèi)汽車行業(yè)的老大哥,比亞迪今年的動作非常多,先是開啟高端品牌
-
山東泰山又遭受裁判雙標(biāo)!離隊(duì)第一人出現(xiàn)!韓镕澤離開才有機(jī)會!
山東泰山又遭受裁判雙標(biāo)!離隊(duì)第一人出現(xiàn)!韓镕澤離開才有機(jī)會!,王雷,
-
金侖控股有限公司(01783.HK)年度凈虧損3810萬港元 毛利率約5.3%
格隆匯6月23日丨金侖控股有限公司(01783 HK)公布,截至2023年3月31日止
-
男生學(xué)會如何用紙制作立方體骰子,打造特色送禮,用心感動女友 最新
你需要的東西紙剪刀磁帶筆尺子或者用來測量的東西您是否感到無聊并
-
美國海岸警衛(wèi)隊(duì)炮艦跑到中國沿海,管得也太寬了吧? 天天看點(diǎn)
“斯特拉頓”號過航臺海并公開炒作。中國海警艦艇對其全程公開跟監(jiān)警戒
-
當(dāng)前要聞:“撐傘女孩”找到了!民警到校頒獎
“撐傘女孩”找到了!經(jīng)過警方多方尋找在烈日下救助中暑老人的“撐傘女
-
高偉光、張雨綺主演《繁華似錦》定檔,這是部怎樣的影視作品?
這是一部小員工和霸道總裁互相影響的影視作品,男女主人公的標(biāo)簽分別為
-
嘉里建設(shè):獨(dú)立非執(zhí)行董事張亮辭任
張亮先生已提出辭任本公司獨(dú)立非執(zhí)行董事,并將于2023年6月30日起生效
-
iQOO 10 Pro和紅魔7s pro對比介紹 當(dāng)前要聞
隨著智能手機(jī)推出的越來越快,各個品牌的旗艦機(jī)型更是早已不滿足一年一
-
fm電臺(fm)_天天熱推薦
來為大家解答以上問題,fm電臺,fm很多人還不知道,現(xiàn)在讓我們一起來看
- 科技創(chuàng)新 賦能生態(tài)環(huán)境教育
- 2021年度北京香山論壇專家視頻會閉幕
- “祖沖之二號”實(shí)現(xiàn)超導(dǎo)體系“量子計算優(yōu)越性”
- 113個光子的量子計算原型機(jī)“九章二號”研制成功
- 傳感器產(chǎn)業(yè)“盛宴”開啟 國產(chǎn)化道路任重道遠(yuǎn)
- 國務(wù)院印發(fā)《2030年前碳達(dá)峰行動方案》
- 就《2030年前碳達(dá)峰行動方案》專訪國家發(fā)展改革委負(fù)責(zé)人
- 自動駕駛 駛進(jìn)生活
- 卡塔爾埃米爾塔米姆會見王毅
- 內(nèi)蒙古包頭發(fā)生多車連撞事故 已致5死11傷