用java寫數組並循環輸入數據「java數組增加元素的方法」

一、概述

對於Java開發而言,使用集合那是家常便飯的事情,這其中ArrayList可能是使用比較多了,用起來也是相當的簡單,通常就是new一個ArrayList,然後往裡面添加元素,但是你真的了解往裡面添加元素的時候,其內部發生了什麼嗎?

往ArrayList裡面添加元素的時候,發生了什麼操作,你了解嗎?

二、源碼解讀

1、相關的內部參數DEFAULT_CAPACITY:默認初始容量EMPTY_ELEMENTDATA:空實例對象的默認數組DEFAULTCAPACITY_EMPTY_ELEMENTDATA:與EMPTY_ELEMENTDATA類似,主要用於區分在首次添加元素時判斷如何進行擴容elementData:ArrayList中實際存儲元素的Object數組size:ArrayList中實際包含的元素數量
2、構造函數

ArrayList()

執行第一行代碼的時候,有如下操作:

就是將ArrayList的elementData引用指向內置的默認對象數組。

public ArrayList(int initialCapacity)

  1. 如果傳入的容量大小大於0,則將內置的elementData指向一個新的Object數組(數組大小為initialCapacity)
  2. 如果initialCapacity值為0,則將elementData引用指向EMPTY_ELEMENTDATA這個內部Object數組。
  3. 如果以上兩者均不滿足的話,則會拋出IllegalArgumentException並附帶initialCapacity參數。

3、add方法解析

add(E, e)

我們首先來看下這個方法

我們先跳過第一行代碼,看第二行,它執行的是將elementData數組中size++位置的元素指定為傳入的參數,在最開始我們就知道,size是數組的實際大小,這就非常好理解了,它執行了size++後,那elementData[size]++這個位置就是數組中的最後一個位置了,因此也就有了添加在最末尾的效果,添加成功後,第三行返回true,這沒什麼好說的,重點來看下第一行,ensureCapacityInternal這個方法,代碼如下:

 private void ensureCapacityInternal(int minCapacity) {
 		if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
			 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
 }

 ensureExplicitCapacity(minCapacity);
 }

首先,判斷elementData存的是否是空數組,如果是,則需要的容量就是默認容量,也就是10,接下來就執行ensureExplicitCapacity,來判斷是否需要擴容。我們來看下這個方法:

 private void ensureExplicitCapacity(int minCapacity) {
 modCount++;

 // overflow-conscious code 注意這個注釋
 if (minCapacity - elementData.length > 0)
 grow(minCapacity);
 }

很明顯,grow方法就是那個擴容方法,什麼時候執行呢?就是當需要的最小容量比現在存得數組的長度大的時候,需要進行擴容。這個有地方需要思考下,就是minCapacity – elementData.length > 0是不是能換成minCapacity > elementData.length這種寫法呢?

我們再來看下grow方法:

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

這邊先獲取既存數組的容量,讓後將這個值擴大1.5倍得到新的容量值,(oldCapacity >> 1這個右移一位就是除以2),然後再判斷擴大後的容量是不是小於需要的最小容量,是的話,將最小容量賦值給新的容量值,不然的話判斷新的容量值是否大於MAX_ARRAY_SIZE這個值,是的話,將hugeCapacity的返回值賦給新的容量值,我們來看下hugeCapacity方法:

 private static int hugeCapacity(int minCapacity) {
 if (minCapacity < 0) // overflow
 throw new OutOfMemoryError();
 return (minCapacity > MAX_ARRAY_SIZE) ?
 Integer.MAX_VALUE :
 MAX_ARRAY_SIZE;
 }

這邊可以看出來,如果需要的最小容量小於0,拋出異常,否則如果需要的最小容量大於MAX_ARRAY_SIZE,則取Integer.MAX_VALUE,否則取MAX_ARRAY_SIZE。

這個就是arrayList執行Add的過程,如果通過無參構造的話,初始數組容量為0,當真正對數組進行添加時,才真正分配容量。每次按照1.5倍(位運算)的比率通過copeOf的方式擴容。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/274453.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-17 14:13
下一篇 2024-12-17 14:13

相關推薦

發表回復

登錄後才能評論