Ich habe vor 2 Monaten einen Blog-Beitrag zum Thema geschrieben. Der Artikel ist für C #, List<T>aber Java ArrayListhat eine sehr ähnliche Implementierung. Da ArrayListes mithilfe eines dynamischen Arrays implementiert wird, nimmt es bei Bedarf an Größe zu. Der Grund für den Kapazitätskonstruktor liegt also in Optimierungszwecken.
Wenn eine dieser Größenänderungsvorgänge ausgeführt wird, kopiert die ArrayList den Inhalt des Arrays in ein neues Array, das doppelt so groß ist wie das alte. Diese Operation läuft in O (n) Zeit.
Beispiel
Hier ist ein Beispiel, wie sich die ArrayListGröße erhöhen würde:
10
16
25
38
58
... 17 resizes ...
198578
297868
446803
670205
1005308
Die Liste beginnt also mit einer Kapazität von 10: Wenn das 11. Element hinzugefügt wird, wird es um 50% + 1bis erhöht 16. Ab dem 17. Punkt ArrayListwird der Wert erneut erhöht 25und so weiter. Betrachten Sie nun das Beispiel, in dem wir eine Liste erstellen, in der die gewünschte Kapazität bereits als bekannt ist 1000000. Wenn Sie den ArrayListKonstruktor ohne Größe erstellen, werden ArrayList.add 1000000Zeiten aufgerufen , die normalerweise O (1) oder O (n) beim Ändern der Größe benötigen.
1000000 + 16 + 25 + ... + 670205 + 1005308 = 4015851 Operationen
Vergleichen Sie dies mit dem Konstruktor und rufen Sie dann auf, ArrayList.addwas garantiert in O (1) ausgeführt wird .
1000000 + 1000000 = 2000000 Operationen
Java vs C #
Java ist wie oben und beginnt bei 10und erhöht jede Größenänderung bei 50% + 1. C # beginnt bei 4und steigt viel aggressiver an und verdoppelt sich bei jeder Größenänderung. Das 1000000Beispiel von oben für C # verwendet 3097084Operationen.
Verweise