Ukuran awal untuk ArrayList

257

Anda dapat mengatur ukuran awal untuk ArrayList dengan melakukan

ArrayList<Integer> arr=new ArrayList<Integer>(10);

Namun, Anda tidak bisa melakukannya

arr.add(5, 10);

karena menyebabkan pengecualian di luar batas.

Apa gunanya mengatur ukuran awal jika Anda tidak dapat mengakses ruang yang Anda alokasikan?

Fungsi add didefinisikan add(int index, Object element)jadi saya tidak menambahkan ke indeks 10.

Cemre
sumber
52
Sebenarnya, tidak jelas dari dokumen bahwa daftar harus memiliki setidaknya n item yang ditambahkan sebelum Anda dapat set/additem n-1 .
Persepsi
5
Persepsi: Saya tidak tahu apakah itu jelas, tetapi sudah ditentukan. Kita harus membaca JavaDoc dengan seksama. Throws: IndexOutOfBoundsException - jika indeks di luar kisaran (indeks <0 || indeks> = ukuran ()).
Natix
3
Hm, konstruktor mengatakan "Constructs daftar kosong dengan kapasitas awal yang ditentukan.", Mengambil gagasan daftar kosong, ada tidak bisa menjadi indeks 5. Tapi saya setuju bahwa kekuatan ini tidak terlihat pada pandangan pertama ...
quaylar
12
Saya pikir itu juga adil untuk mengatakan bahwa jika Anda menginisialisasi array ke nilai tertentu, Anda akan menganggap indeks lebih rendah dari nilai yang tersedia — dan ini adalah ArrayList. Saya, secara pribadi, ingin metode yang memungkinkan saya untuk mengatur ukuran sedemikian rupa sehingga saya dapat menempatkan sesuatu pada indeks tertentu. Metode ini tampaknya tidak ada.
Andrew Wyld
1
Numbskull apa yang merancang koleksi seperti ini ?! Ini memaksa kerja yang berlebihan untuk instantiasi paralel dari suatu struktur dengan elemen-elemen panjang variabel (yaitu ArrayList <String []> di mana setiap array dapat memiliki panjang yang berbeda). Jika memori sudah dialokasikan sehingga daftar tidak perlu realokasi setelah menambahkan elemen N, indeks tersebut harus dapat diakses langsung dari awal. Tidak ada seorang pun di Oracle yang mempelajari pola ini setelah C / C ++, C #, Objective C, dan Swift ?!
patrickjp93

Jawaban:

387

Anda mengacaukan ukuran daftar array dengan kapasitasnya:

  • yang ukuran adalah jumlah elemen dalam daftar;
  • yang kapasitas adalah berapa banyak elemen daftar berpotensi dapat menampung tanpa merealokasi struktur internal.

Saat Anda menelepon new ArrayList<Integer>(10), Anda mengatur kapasitas awal daftar , bukan ukurannya. Dengan kata lain, ketika dibangun dengan cara ini, daftar array mulai kosong.

Salah satu cara untuk menambahkan sepuluh elemen ke daftar array adalah dengan menggunakan loop:

for (int i = 0; i < 10; i++) {
  arr.add(0);
}

Setelah melakukan ini, Anda sekarang dapat memodifikasi elemen di indeks 0..9.

NPE
sumber
51
+1: Lingkaran yang lebih pendek while(arr.size() < 10) arr.add(0);Ini dapat bermanfaat untuk mengatakan, ukurannya harus setidaknya 10. mis. sehingga Anda dapat menggunakanarr.set(9, n);
Peter Lawrey
10
+1: Respons yang bagus, saya akan memberi +10 jika saya bisa. Tidak jelas dari api mengapa Anda tidak dapat mengatur KEDUA ukuran awal dan kapasitas awal dalam panggilan konstruktor tunggal. Anda semacam harus membaca api dan berkata "Oh, saya kira ArrayList tidak memiliki metode atau konstruktor untuk melakukan itu"
demongolem
@PeterLawrey Kode Anda mungkin lebih pendek, tetapi berisi dua pemanggilan metode per pengulangan, bukan hanya satu.
neuralmer
@neuralmer Saya berharap ukuran () dan menambahkan () akan diuraikan sehingga tidak ada panggilan metode yang sebenarnya terjadi saat runtime.
Peter Lawrey
109

Jika Anda ingin daftar dengan ukuran yang telah ditentukan, Anda juga dapat menggunakan:

List<Integer> arr = Arrays.asList(new Integer[10]);
Gert Jan Schoneveld
sumber
11
Sedikit kerugian di sini, hasilnya Listpenuh dengan nol. Dengan Guava kita bisa melakukan Ints.asList(new int[10])yang akan menginisialisasi daftar kita dengan 0s. Bersihkan pola, terima kasih untuk contohnya.
dimo414
1
Pertanyaan berbicara tentang ArrayList <E>. Anda menggunakan Daftar <E>. Tidak ada yang mengamati ini ??? Selain itu, mereka telah mengangkat jawaban yang tidak relevan ini ! Saya tidak menurunkan jawaban Anda karena saya tidak pernah melakukannya. Sederhananya ... Demi Tuhan!
Apostolos
3
@Apostolos ArrayListadalah implementasi dari Listantarmuka dan Arrays.asListmengembalikan sebuah ArrayList. Saya sarankan Anda mencari polimorfisme.
Liam Potter
Ini mengembalikan Daftar dengan ukuran tetap. Mencoba menambahkan lebih banyak elemen lemparanUnsupportedOperationException
Koray Tugay
47

jika Anda ingin menggunakan Collections.fill (daftar, obj); untuk mengisi daftar dengan objek yang diulang atau Anda dapat menggunakan

ArrayList<Integer> arr=new ArrayList<Integer>(Collections.nCopies(10, 0));

salinan baris 10 kali 0 ke ArrayList Anda

Farzan Skt
sumber
20

Kapasitas suatu ArrayListtidak sama dengan ukurannya . Ukuran sama dengan jumlah elemen yang terkandung dalam ArrayList(dan Listimplementasi lainnya ).

The kapasitas hanya panjang array yang mendasari yang digunakan untuk internaly menyimpan unsur-unsur ArrayList, dan selalu lebih besar atau sama dengan ukuran dari daftar.

Saat memanggil set(index, element)daftar, ini indexberkaitan dengan jumlah aktual elemen daftar (= ukuran) (yang merupakan nol dalam kode Anda, oleh karena AIOOBEitu dilemparkan), bukan dengan panjang array (= kapasitas) (yang merupakan detail implementasi spesifik ke ArrayList).

The setmetode adalah umum untuk semua Listimplementasi, seperti LinkedList, yang tidak benar-benar dilaksanakan oleh sebuah array, tetapi sebagai rantai terkait entri.

Sunting : Anda sebenarnya menggunakan add(index, element)metode ini, bukan set(index, element), tetapi prinsipnya sama di sini.

Natix
sumber
10

Jika Anda ingin menambahkan elemen dengan indeks, Anda bisa menggunakan array.

    String [] test = new String[length];
    test[0] = "add";
pengguna3692587
sumber
5
OP ingin menggunakan Daftar pada awalnya ... bukan array.
Stephan
9

10 adalah kapasitas awal AL, bukan ukuran (yaitu 0). Anda harus menyebutkan kapasitas awal ke beberapa nilai tinggi ketika Anda akan memiliki banyak elemen, karena itu menghindari overhead dari peningkatan kapasitas saat Anda terus menambahkan elemen.

Bhesh Gurung
sumber
6

Saya kira jawaban yang tepat untuk pertanyaan Anda adalah:

Mengatur ukuran awal pada ArrayList mengurangi nr. alokasi memori internal kali harus terjadi. Daftar ini didukung oleh sebuah array. Jika Anda menentukan kapasitas awal yaitu 0, sudah pada penyisipan pertama elemen array internal harus diubah ukurannya. Jika Anda memiliki gagasan perkiraan tentang berapa banyak elemen yang akan disimpan oleh daftar Anda, pengaturan kapasitas awal akan mengurangi angka. alokasi ulang memori yang terjadi saat Anda menggunakan daftar.

quaylar
sumber
3

Ini mungkin membantu seseorang -

ArrayList<Integer> integerArrayList = new ArrayList<>(Arrays.asList(new Integer[10]));
Hrishikesh Kadam
sumber
3

Terlambat dalam hal ini, tetapi setelah Java 8 , saya pribadi menemukan pendekatan berikut dengan StreamAPI lebih ringkas dan dapat menjadi alternatif untuk jawaban yang diterima .

Sebagai contoh,

Arrays.stream(new int[size]).boxed().collect(Collectors.toList())

di mana ukuran yang sizediinginkan Listdan tanpa kerugian yang disebutkan di sini , semua elemen dalam Listdiinisialisasi sebagai 0.

(Saya melakukan pencarian cepat dan tidak melihat streamjawaban yang diposting - jangan ragu untuk memberi tahu saya jika jawaban ini berlebihan dan saya dapat menghapusnya)

HT Koo
sumber
1

Saat ini tidak ada elemen dalam daftar Anda sehingga Anda tidak dapat menambahkan ke indeks 5 daftar ketika itu tidak ada. Anda mengacaukan kapasitas daftar dengan ukurannya saat ini.

Panggil saja:

arr.add(10)

untuk menambahkan Integer ke ArrayList Anda

Hunter McMillen
sumber
1

Meskipun daftar array Anda memiliki kapasitas 10, daftar sebenarnya tidak memiliki elemen di sini. Metode add digunakan untuk menyisipkan elemen ke daftar nyata. Karena tidak memiliki elemen, Anda tidak dapat memasukkan elemen ke indeks 5.

roll1987
sumber
1

Jika Anda ingin menambahkan 10 item ke Anda, ArrayListAnda dapat mencobanya:

for (int i = 0; i < 10; i++)
    arr.add(i);

Jika Anda sudah mendeklarasikan variabel ukuran array, Anda akan menggunakan variabel sizealih-alih angka '10'

harimau kumbang
sumber
1

Saya dihadapkan dengan masalah yang sama, dan hanya mengetahui arrayList adalah implementasi array-resizable dari antarmuka Daftar, saya juga berharap Anda dapat menambahkan elemen ke titik mana pun, tetapi setidaknya memiliki opsi untuk menentukan ukuran awal. Bagaimanapun, Anda dapat membuat array terlebih dahulu dan mengonversinya menjadi daftar seperti:

  int index = 5;
  int size = 10;

  Integer[] array = new Integer[size];
  array[index] = value;
  ...
  List<Integer> list = Arrays.asList(array);

atau

  List<Integer> list = Arrays.asList(new Integer[size]);
  list.set(index, value);
unk
sumber
0

ArrayList myList = new ArrayList (10);

//  myList.add(3, "DDD");
//  myList.add(9, "III");
    myList.add(0, "AAA");
    myList.add(1, "BBB");

    for(String item:myList){
        System.out.println("inside list : "+item);
    }

/ * Menyatakan kapasitas awal dari arraylist hanyalah menghemat waktu pergeseran secara internal; ketika kita menambahkan elemen secara internal itu memeriksa kapasitas untuk meningkatkan kapasitas, Anda bisa menambahkan elemen pada 0 indeks awalnya lalu 1 dan seterusnya. * /

sambhu
sumber
0

Dua sen saya menyala Stream. Saya pikir lebih baik digunakan

IntStream.generate(i -> MyClass.contruct())
         .limit(INT_SIZE)
         .collect(Collectors.toList());

dengan fleksibilitas untuk menempatkan nilai awal apa pun.

anch2150
sumber