Jak mogę zainicjować ArrayList ze wszystkimi zerami w Javie?

161

Wygląda na arraylistto, że nie wykonuje swojego zadania w zakresie zmiany rozmiaru:

// presizing 

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

Później, gdy próbuję uzyskać do niego dostęp:

list.get(5) 

Zamiast zwracać 0, zgłasza IndexOutOfBoundsException: Indeks 5 poza zakresem dla długości 0 .

Czy istnieje sposób na zainicjowanie wszystkich elementów do 0 o dokładnym rozmiarze, tak jak robi to C ++?

Mróz
źródło
4
Dokument Javadoc tego konstruktora określa, że ​​tworzy on „pustą listę”. Wykonuje swoją pracę.
ColinD,

Odpowiedzi:

429

Liczba całkowita przekazana do konstruktora reprezentuje jego początkową pojemność , tj. Liczbę elementów, które może przechowywać, zanim będzie musiał zmienić rozmiar swojej wewnętrznej tablicy (i nie ma nic wspólnego z początkową liczbą elementów na liście).

Aby zainicjować listę z 60 zerami, wykonaj:

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

Jeśli chcesz utworzyć listę z 60 różnymi obiektami, możesz użyć interfejsu Stream API w Suppliernastępujący sposób:

List<Person> persons = Stream.generate(Person::new)
                             .limit(60)
                             .collect(Collectors.toList());
aioobe
źródło
1
To znacznie lepsze niż moje rozwiązanie (nawet moje zaktualizowane, które faktycznie działa hehehe). Nie radziłbym jednak robić z tego nowego ArrayList, a zamiast tego po prostu zaprogramować List. To oczywiście decyzja pozostawiona OP.
corsiKa
6
Lista zwrócona przez nCopiesjest niezmienna, więc utworzenie nowej ArrayListjest prawdopodobnie dobrym pomysłem.
aioobe
4
Uważaj, gdy używasz nCopiesobiektu z obiektem złożonym, kolekcja nie jest tworzona z 60 różnymi obiektami, ale 60 razy z tym samym obiektem. Więc używaj tego tylko dla prymitywów.
członkowie około
1
@membersound, przychodzi mi do głowy wiele scenariuszy, w których nCopiesjest to przydatne w przypadku typów referencyjnych: niezmienne obiekty, takie jak ciągi znaków, wzorce obiektów null, stałe wyliczeniowe ... W każdym razie zaktualizowałem odpowiedź o rozwiązanie umożliwiające tworzenie 60 różnych obiektów.
aioobe
@aioobe Wiem, że istnieje wiele scenariuszy, w których ncopies jest przydatne. Chciałem to tylko dodać, ponieważ próbowałem ncopies ze zmiennymi obiektami i byłem zaskoczony, że nie działa tak, jak się spodziewałem. Na wypadek, gdyby ktoś spróbował tego samego zadania. dzięki za aktualizację!
członkowie około
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
źródło
2
Spowoduje to jedynie wypełnienie listy istniejącymi wpisami. Nie zainicjuje go elementami zgodnie z potrzebami.
WhiteFang34
To nie wypełni listy 60 zerami.
aioobe
Nawet gdyby stworzył 60 obiektów, w których nie musi żadnych.
ColinD,
1
@Frost: dostaniesz IndexOutOfBoundsExceptionzList<Integer> list = new ArrayList<Integer>(60); Collections.fill(list, new Integer(0)); list.get(5);
WhiteFang34
1
Arrays.asListtworzy List, który nie pozwala na dodawanie ani usuwanie, więc nie jest dokładnie tym samym, czego chce OP. Zadziałałoby, gdyby wszystko, co musisz zrobić, to set, ale w takim przypadku lepiej byłoby po prostu użyć tablicy.
ColinD,
8

60, które mijasz, to tylko początkowa pojemność pamięci wewnętrznej. To podpowiedź, jak duże myślisz, że może być, ale oczywiście nie jest to ograniczone. Jeśli chcesz ustawić wartości, musisz ustawić je samodzielnie, np:

for (int i = 0; i < 60; i++) {
    list.add(0);
}
WhiteFang34
źródło
4

Implementacja Java 8 (lista inicjowana 60zerami) :

List<Integer> list = IntStream.of(new int[60])
                    .boxed()
                    .collect(Collectors.toList());
  • new int[N] - tworzy tablicę wypełnioną zerami i długością N
  • boxed() - każdy element opakowany w liczbę całkowitą
  • collect(Collectors.toList()) - zbiera elementy strumienia
am0wa
źródło
0

To nie tak. ArrayList po prostu używa tablicy jako wewnętrznej respentacji. Jeśli dodasz więcej niż 60 elementów, to tablica podkładania zostanie rozszerzona. Jakkolwiek możesz dodać tyle elementów do tej tablicy, ile masz pamięci RAM.

Marcin
źródło