Как я могу инициализировать 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 различных объектов, вы можете использовать Stream API со Supplierследующим:

List<Person> persons = Stream.generate(Person::new)
                             .limit(60)
                             .collect(Collectors.toList());
aioobe
источник
1
Это намного лучше, чем мое решение (даже мое обновленное, которое действительно работает хе-хе-хе). Я бы порекомендовал не делать из этого новое ArrayList, а просто программировать на List. Это решение осталось за ФП, конечно.
corsiKa
6
Список, возвращаемый nCopiesнеизменным, поэтому, ArrayListвероятно, хорошая идея - создать новый .
aioobe
4
Помните, что при использовании nCopiesсо сложным объектом коллекция создается не с 60 различными объектами, а 60 раз с одним и тем же объектом. Так что используйте это только для примитивов.
membersound
1
@membersound, я могу вспомнить множество сценариев, в которых nCopiesполезно использовать ссылочные типы: неизменяемые объекты, такие как строки, шаблоны нулевых объектов, константы перечисления, ... В любом случае, я обновил ответ решением для создания 60 различных объектов.
aioobe
@aioobe Я знаю, что во многих случаях полезно использовать ncopies. Я просто хотел добавить это, так как я пытался копировать с изменяемыми объектами и был удивлен, что это не сработало, как я ожидал. На всякий случай, если кто-нибудь попробует ту же задачу. спасибо за обновление, хотя!
membersound
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);
corsiKa
источник
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
2
Arrays.asListпроизводит, Listчто не позволяет добавлять или удалять, так что это не совсем то, что хочет ОП. Это сработало бы, если бы все, что вам нужно было сделать set, но вам лучше использовать массив в этом случае.
ColinD
8

60, которые вы передаете, это просто начальная емкость для внутреннего хранилища. Это намек на то, насколько большим вы думаете, он может быть, но, конечно, этим не ограничивается. Если вам нужно предварительно установить значения, вам придется установить их самостоятельно, например:

for (int i = 0; i < 60; i++) {
    list.add(0);
}
WhiteFang34
источник
4

Реализация Java 8 (список инициализируется 60нулями) :

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

Это не так. ArrayList просто использует массив как внутреннее восстановление. Если вы добавите более 60 элементов, нижележащий массив будет расширен. Как бы то ни было, вы можете добавить столько элементов в этот массив, сколько у вас оперативной памяти.

Marcin
источник