Der Auslöser war Ich habe die Quelle von ArrayList gelesen. Ich habe geschrieben, woran ich interessiert war ich habe die Quelle von ArrayList gelesen, aber ich habe es weiter gelesen und war interessiert ist.
"Ich verstehe den Unterschied zwischen LL.116-126 EMPTY_ELEMENT DATA und DEFAULTCAPACITY_EMPTY_ELEMENTDATA nicht. Verstehst du, wenn du weiter liest? Der letztere Javadoc sagt jedoch richtig: "Das ist der Unterschied." Solche Kommentare sind wichtig. Aber ich verstehe es immer noch nicht. 』\
Korrekt. Ich weiß, was ich tun möchte, aber ich verstehe nicht die Absicht, es in zwei Variablen aufzuteilen. Nun, ich war neugierig und habe es überprüft.
Dann wurde die Korrektur der ersten Stufe gefunden. Verzögern Sie zunächst die Auswertung des Standardkonstruktors. Wenn es sich um die Quelle des alten JDK handelt, habe ich beim Betrachten des Konstruktors das Gefühl, sofort verstanden zu haben, wie viel Größe durch den Anfangswert gesichert werden sollte. Es ist ein leeres Array. Dies ist derjenige, der es behoben hat. 8011200: (coll) Optimize empty HashMap and ArrayList
public ArrayList() {
// this(10);
super();
this.elementData = EMPTY_ELEMENTDATA;
}
Anstatt zu Beginn 10 Sequenzen zuzuweisen, machen Sie es leer und erweitern Sie es, wenn Sie es hinzufügen. Das ist in Ordnung.
Als nächstes wurde ein Fix für die zweite Stufe gefunden. Hier wird DEFAULTCAPACITY_EMPTY_ELEMENTDATA hinzugefügt. 8035584: ArrayList(c) should avoid inflation if c is empty
Wenn eine leere Liste mit public ArrayList übergeben wird (Collection <? Erweitert E> c) {, wird c.toArray (); aufgerufen und die Anzahl der Instanzen nimmt stetig zu. Wenn also size == 0 ist, setze ich this.elementData = EMPTY_ELEMENTDATA; Ich verstehe das.
Warum haben Sie this.elementData = EMPTY_ELEMENTDATA in this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA geändert, wenn public ArrayList () {? Nun, ich weiß es nicht.
Nach beiden Änderungen zu urteilen, war es, als neue ArrayList () erstellt wurde, ursprünglich neue ArrayList (10). Aber jetzt ersetze ich ein leeres Array. Wenn andererseits eine neue ArrayList (0) ausgeführt wird, wird ein leeres Array zugewiesen. Gleiches gilt, wenn eine leere Liste an den Konstruktor übergeben wird.
Mit anderen Worten, beim erstmaligen Hinzufügen nach dem Erstellen einer Instanz werden DEFAULTCAPACITY_EMPTY_ELEMENTDATA und EMPTY_ELEMENTDATA separat zugewiesen, um zu unterscheiden, ob sie mit neuer ArrayList () oder neuer ArrayList (0) erstellt wurden. ..
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
Der Unterschied zwischen 0 und 10 (DEFAULT_CAPACITY) besteht darin, dass beim Aufruf von sureCapacity (5) die Puffergröße für neue ArrayList () ursprünglich 10 beträgt, daher ignoriert wird und für neue ArrayList (0) die Puffergröße 0 beträgt. Die Entscheidung war, die Puffergröße auf 5 zu erhöhen.
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
Wenn dieses Maximum auch neu ist ArrayList (), bedeutet dies, dass die Puffergröße = 10 (DEFAULT_CAPACITY) plötzlich ist, selbst wenn Sie versuchen, Puffergröße = 0 hinzuzufügen und Puffergröße = 1 festzulegen.
Beheben Sie keine andere Sache zusammen mit dem Fix "ArrayList (c) sollte Inflation vermeiden, wenn c leer ist". Vielleicht steht es irgendwo geschrieben.
Recommended Posts