Я фактически написал сообщение в блоге на тему 2 месяца назад. Статья предназначена для C #, List<T>но Java ArrayListимеет очень похожую реализацию. Так ArrayListкак реализован с использованием динамического массива, он увеличивается в размере по требованию. Поэтому причина для конструктора емкости - в целях оптимизации.
Когда происходит одна из этих операций изменения размеров, ArrayList копирует содержимое массива в новый массив, который в два раза больше емкости старого. Эта операция выполняется за O (n) времени.
пример
Вот пример того, как ArrayListразмер увеличится:
10
16
25
38
58
... 17 resizes ...
198578
297868
446803
670205
1005308
Таким образом, список начинается с емкости 10, при добавлении 11-го элемента он увеличивается 50% + 1до 16. На 17-м пункте ArrayListснова увеличен до 25и так далее. Теперь рассмотрим пример, в котором мы создаем список, в котором желаемая емкость уже известна как 1000000. Создание конструктора ArrayListбез размера вызовет ArrayList.add 1000000время, которое обычно занимает O (1) или O (n) при изменении размера.
1000000 + 16 + 25 + ... + 670205 + 1005308 = 4015851 операций
Сравните это, используя конструктор, а затем вызов, ArrayList.addкоторый гарантированно будет выполняться в O (1) .
1000000 + 1000000 = 2000000 операций
Java против C #
Java как и выше, начиная с 10каждого размера и увеличивая его 50% + 1. C # начинается 4и увеличивается гораздо агрессивнее, удваивается при каждом изменении размера. Добавленный 1000000пример сверху для C # использует 3097084операции.
Ссылки