Bagaimana saya bisa menginisialisasi ArrayList dengan semua nol di Jawa?

161

Sepertinya arraylisttidak melakukan tugasnya untuk mengatur:

// presizing 

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

Setelah itu ketika saya mencoba mengaksesnya:

list.get(5) 

Alih-alih mengembalikan 0 itu melempar IndexOutOfBoundsException: Indeks 5 dari batas untuk panjang 0 .

Apakah ada cara untuk menginisialisasi semua elemen ke 0 dengan ukuran yang tepat seperti apa yang dilakukan C ++?

Embun beku
sumber
4
Javadoc dari konstruktor itu menetapkan bahwa ia membuat "daftar kosong". Ia melakukan tugasnya.
ColinD

Jawaban:

429

Bilangan bulat yang diteruskan ke konstruktor mewakili kapasitas awalnya , yaitu jumlah elemen yang dapat dipegang sebelum perlu mengubah ukuran array internal (dan tidak ada hubungannya dengan jumlah awal elemen dalam daftar).

Untuk menginisialisasi daftar dengan 60 nol Anda lakukan:

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

Jika Anda ingin membuat daftar dengan 60 objek berbeda , Anda bisa menggunakan Stream API dengan Suppliersebagai berikut:

List<Person> persons = Stream.generate(Person::new)
                             .limit(60)
                             .collect(Collectors.toList());
aioobe
sumber
1
Itu jauh lebih baik daripada solusi saya (bahkan yang saya perbarui yang benar-benar berfungsi hehehe). Saya akan merekomendasikan untuk tidak membuat yang baru ArrayList, dan sebaliknya hanya memprogram untuk List. Itu keputusan yang tersisa untuk OP, tentu saja.
corsiKa
6
Daftar yang dikembalikan nCopiestidak dapat diubah, jadi membuat yang baru ArrayListmungkin merupakan ide yang bagus.
aioobe
4
Berhati-hatilah bahwa ketika menggunakan nCopiesobjek yang kompleks, koleksi tidak dibuat dengan 60 objek yang berbeda, tetapi 60 kali dengan objek yang sama. Jadi hanya gunakan ini untuk primitif.
membersound
1
@membersound, saya bisa memikirkan banyak skenario di mana nCopiesberguna dengan jenis referensi: objek tidak berubah seperti string, pola null-objek, konstanta enum, ... Pokoknya, saya memperbarui jawaban dengan solusi untuk membuat 60 objek yang berbeda.
aioobe
@aioobe Saya tahu ada banyak skenario di mana ncopies berguna. Saya hanya ingin menambahkan ini, ketika saya mencoba ncopies dengan benda yang bisa berubah dan terkejut itu tidak berfungsi seperti yang saya harapkan. Kalau-kalau ada yang mencoba tugas yang sama. terima kasih atas pembaruannya!
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
sumber
2
Ini hanya mengisi daftar dengan entri yang ada. Itu tidak akan menginisialisasi dengan elemen yang diinginkan.
WhiteFang34
Ini tidak akan mengisi daftar dengan 60 nol.
aioobe
Bahkan jika itu akan membuat 60 objek di mana ia tidak harus membuatnya.
ColinD
1
@ Frost: Anda akan mendapatkan IndexOutOfBoundsExceptiondenganList<Integer> list = new ArrayList<Integer>(60); Collections.fill(list, new Integer(0)); list.get(5);
WhiteFang34
2
Arrays.asListmenghasilkan a Listyang tidak mengizinkan penambahan atau penghapusan, jadi itu tidak persis sama dengan apa yang diinginkan OP. Ini akan bekerja jika semua yang perlu Anda lakukan adalah set, tetapi Anda mungkin lebih baik menggunakan array saja.
ColinD
8

60 yang Anda lewati hanyalah kapasitas awal untuk penyimpanan internal. Ini adalah petunjuk tentang seberapa besar Anda pikir itu mungkin, namun tentu saja itu tidak dibatasi oleh hal itu. Jika Anda perlu menetapkan nilai, Anda harus mengaturnya sendiri, misalnya:

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

Implementasi Java 8 (Daftar diinisialisasi dengan 60nol) :

List<Integer> list = IntStream.of(new int[60])
                    .boxed()
                    .collect(Collectors.toList());
  • new int[N] - Membuat array yang diisi dengan nol & panjang N
  • boxed() - setiap elemen dikotakkan ke Integer
  • collect(Collectors.toList()) - Mengumpulkan elemen aliran
am0wa
sumber
0

Tidak seperti itu. ArrayList hanya menggunakan array sebagai respentasi internal. Jika Anda menambahkan lebih dari 60 elemen maka array yang mendasari akan ditampilkan. Bagaimana pun Anda dapat menambahkan elemen ke array ini sebanyak RAM yang Anda miliki.

Marcin
sumber