Na verdade, eu escrevi um post sobre o tópico há 2 meses. O artigo é para C #, List<T>
mas o Java ArrayList
tem uma implementação muito semelhante. Como ArrayList
é implementado usando uma matriz dinâmica, aumenta em tamanho sob demanda. Portanto, o motivo do construtor de capacidade é para fins de otimização.
Quando uma dessas operações de redimensionamento ocorre, o ArrayList copia o conteúdo da matriz em uma nova matriz com o dobro da capacidade da antiga. Esta operação é executada em O (n) tempo.
Exemplo
Aqui está um exemplo de como o ArrayList
tamanho aumentaria:
10
16
25
38
58
... 17 resizes ...
198578
297868
446803
670205
1005308
Portanto, a lista começa com uma capacidade de 10
, quando o 11º item é adicionado, é aumentado em 50% + 1
para 16
. No 17º item, o valor ArrayList
é aumentado novamente para 25
e assim por diante. Agora considere o exemplo em que estamos criando uma lista em que a capacidade desejada já é conhecida 1000000
. Criar o ArrayList
construtor sem o tamanho chamará ArrayList.add
1000000
tempos que levam O (1) normalmente ou O (n) no redimensionamento.
1000000 + 16 + 25 + ... + 670205 + 1005308 = 4015851 operações
Compare isso usando o construtor e, em seguida, chamando, ArrayList.add
que é garantido para executar em O (1) .
1000000 + 1000000 = 2000000 operações
Java vs C #
Java é como acima, iniciando 10
e aumentando cada redimensionamento em 50% + 1
. O C # inicia 4
e aumenta muito mais agressivamente, dobrando a cada redimensionamento. O 1000000
exemplo adiciona acima para C # usa 3097084
operações.
Referências