Як я можу ініціалізувати ArrayList зі всіма нулями в Java?


161

Схоже arraylist, не виконує свою роботу з призначення президенти:

// presizing 

ArrayList<Integer> list = new ArrayList<Integer>(60);

Потім, коли я намагаюся отримати доступ до нього:

list.get(5) 

Замість повернення 0 він кидає IndexOutOfBoundsException: індекс 5 виходить за межі довжини 0 .

Чи є спосіб ініціалізувати всі елементи до 0 точного розміру, як це робить C ++?


4
Javadoc цього конструктора вказує, що він створює "порожній список". Це робить свою справу.
ColinD

Відповіді:


429

Ціле число, передане конструктору, представляє його початкову ємність , тобто кількість елементів, які він може утримувати, перш ніж йому потрібно змінити розмір внутрішнього масиву (і не має нічого спільного з початковою кількістю елементів у списку).

Щоб ініціалізувати список із 60 нулями, виконайте такі дії:

List<Integer> list = new ArrayList<Integer>(Collections.nCopies(60, 0));

Якщо ви хочете створити список із 60 різними об'єктами, ви можете використовувати API Stream із Supplierнаступним чином:

List<Person> persons = Stream.generate(Person::new)
                             .limit(60)
                             .collect(Collectors.toList());

1
Це набагато краще, ніж моє рішення (навіть моє оновлене, яке насправді працює hehehe). Я б рекомендував не робити нове ArrayListз цього, але замість цього просто програмувати List. Це, звичайно, рішення, що залишається ОП.
corsiKa

6
Список, який повертається, nCopiesє незмінним, тому створення нового ArrayList, мабуть, хороша ідея.
aioobe

4
Слідкуйте за тим, що при використанні nCopiesзі складним об'єктом колекція складається не з 60 різних об'єктів, але 60 разів з тим самим об'єктом. Тож використовуйте це лише для примітивів.
члени звучання

1
@membersound, я можу придумати багато сценаріїв, де nCopiesце корисно для посилальних типів: незмінні об'єкти, такі як рядки, нульові об'єкти, константи перерахунку, ... У будь-якому разі я оновив відповідь рішенням для створення 60 різних об'єктів.
aioobe

@aioobe Я знаю, що існує безліч сценаріїв, коли ncopies корисна. Мені просто хотілося додати це, оскільки я спробував копіювати файли зі змінними об'єктами і був здивований, що це не спрацювало так, як я очікував. Про всяк випадок, коли хтось спробує те саме завдання. дякую за оновлення, хоча!
члени звучання

12
// apparently this is broken. Whoops for me!
java.util.Collections.fill(list,new Integer(0));

// this is better
Integer[] data = new Integer[60];
Arrays.fill(data,new Integer(0));
List<Integer> list = Arrays.asList(data);

2
Це лише заповнює список існуючими записами. Він не буде ініціалізувати його за бажанням елементів.
WhiteFang34

Це не заповнить список 60 нулями.
aioobe

Навіть якби це створило б 60 об'єктів, де не потрібно створювати жодних.
ColinD

1
@Frost: ви отримаєте IndexOutOfBoundsExceptionзList<Integer> list = new ArrayList<Integer>(60); Collections.fill(list, new Integer(0)); list.get(5);
WhiteFang34

1
Arrays.asListстворює Listте, що не дозволяє додавати чи видаляти, тому це не зовсім те, що хоче ОП. Це спрацювало б, якщо все, що вам потрібно зробити set, але вам може бути краще просто використовувати масив у такому випадку.
ColinD

8

60, які ви проходите, - це лише початкова ємність для внутрішнього зберігання. Це натяк на те, якою великою ви вважаєте, що це може бути, але, звичайно, це не обмежується. Якщо вам потрібно задати значення, вам доведеться їх встановити самостійно, наприклад:

for (int i = 0; i < 60; i++) {
    list.add(0);
}

4

Реалізація Java 8 (Список ініціалізований 60нулями) :

List<Integer> list = IntStream.of(new int[60])
                    .boxed()
                    .collect(Collectors.toList());
  • new int[N] - створює масив, заповнений нулями & довжиною N
  • boxed() - кожен елемент, поставлений у коробку до цілого числа
  • collect(Collectors.toList()) - збирає елементи потоку

0

Це не так. ArrayList просто використовує масив як внутрішнє покаяння. Якщо додати більше 60 елементів, то підкладений масив буде збільшений. Як ніколи ви можете додати стільки елементів до цього масиву стільки оперативної пам’яті.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.