Я фактично написав повідомлення в блозі на цю тему 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операції.
Список літератури