De hecho, escribí una publicación de blog sobre el tema hace 2 meses. El artículo es para C #, List<T>
pero Java ArrayList
tiene una implementación muy similar. Dado que ArrayList
se implementa utilizando una matriz dinámica, aumenta de tamaño a pedido. Entonces, la razón del constructor de capacidad es para fines de optimización.
Cuando se produce una de estas operaciones de cambio de tamaño, ArrayList copia el contenido de la matriz en una nueva matriz que tiene el doble de capacidad que la anterior. Esta operación se ejecuta en tiempo O (n) .
Ejemplo
Aquí hay un ejemplo de cómo ArrayList
aumentaría el tamaño:
10
16
25
38
58
... 17 resizes ...
198578
297868
446803
670205
1005308
Entonces, la lista comienza con una capacidad de 10
, cuando se agrega el undécimo elemento, aumenta en 50% + 1
a 16
. En el decimoséptimo elemento, ArrayList
se aumenta nuevamente 25
y así sucesivamente. Ahora considere el ejemplo donde estamos creando una lista donde la capacidad deseada ya se conoce como 1000000
. Crear el ArrayList
constructor sin el tamaño llamará a ArrayList.add
1000000
veces que toma O (1) normalmente u O (n) en el cambio de tamaño.
1000000 + 16 + 25 + ... + 670205 + 1005308 = 4015851 operaciones
Compare esto usando el constructor y luego llamando, ArrayList.add
que se garantiza que se ejecutará en O (1) .
1000000 + 1000000 = 2000000 operaciones
Java vs C #
Java es como el anterior, comenzando en 10
y aumentando cada cambio de tamaño en 50% + 1
. C # comienza en 4
y aumenta mucho más agresivamente, duplicando en cada cambio de tamaño. El 1000000
ejemplo agregado de arriba para C # utiliza 3097084
operaciones.
Referencias