Schauen wir uns diesen Code an (jdk1.8)
@Test
public void testArraySize() throws Exception {
List<String> list = new ArrayList<>();
list.add("ds");
list.add("cx");
list.add("cx");
list.add("ww");
list.add("ds");
list.add("cx");
list.add("cx");
list.add("ww");
list.add("ds");
list.add("cx");
list.add("last");
}
1) Setzen Sie einen Haltepunkt auf die Linie, wenn "last" eingefügt wird
2) Gehen Sie zur Add-Methode von ArrayList
Sie werden sehen
ensureCapacityInternal(size + 1);
elementData[size++] = e;
3) Gehen Sie zur Methode sureCapacityInternal, die diese Methode aufruft ensureExplicitCapacity
4)
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
return true;
In unserem Beispiel ist minCapacity gleich 11, 11-10 > 0
daher benötigen Sie eine grow
Methode
5)
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
Beschreiben wir jeden Schritt:
1) oldCapacity
= 10, da wir diesen Parameter nicht gesetzt haben, als ArrayList
init war, wird daher die Standardkapazität verwendet (10)
2) int newCapacity = oldCapacity + (oldCapacity >> 1);
Hier ist newCapacity gleich oldCapacity plus oldCapacity mit einer Verschiebung nach rechts um eins ( oldCapacity is 10
dies ist die binäre Darstellung, die 00001010
sich um ein Bit nach rechts bewegt, 00000101
was 5 in Dezimalzahl newCapacity
ist 10 + 5 = 15
).
3)
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
Zum Beispiel ist Ihre Init-Kapazität 1, wenn Sie das zweite Element zu arrayList hinzufügen newCapacity
, ist gleich. 1(oldCapacity) + 0 (moved to right by one bit) = 1
In diesem Fall ist newCapacity kleiner als minCapacity und elementData
(Array-Objekt in arrayList) kann kein neues Element enthalten, daher ist newCapacity gleich minCapacity
4)
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
Überprüfen Sie, ob die Arraygröße MAX_ARRAY_SIZE (Integer.MAX - 8) erreicht. Warum ist die maximale Arraygröße von ArrayList Integer.MAX_VALUE - 8?
5) Schließlich werden alte Werte mit der Länge 15 in das newArray kopiert