Secara teknis, ini 10
, bukan nol, jika Anda mengakui inisialisasi larik dukungan yang malas. Lihat:
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
dimana
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
Yang Anda maksud hanyalah objek larik awal berukuran nol yang dibagikan di antara semua objek yang awalnya kosong ArrayList
. Yaitu kapasitas 10
dijamin malas , pengoptimalan yang ada juga di Java 7.
Diakui, kontrak konstruktor tidak sepenuhnya akurat. Mungkin inilah yang menjadi sumber kebingungan di sini.
Latar Belakang
Ini E-Mail oleh Mike Duigou
Saya telah memposting versi terbaru dari ArrayList dan patch HashMap kosong.
http://cr.openjdk.java.net/~mduigou/JDK-7143928/1/webrev/
Implementasi yang direvisi ini tidak memperkenalkan bidang baru ke kedua kelas. Untuk ArrayList, alokasi malas dari backing array hanya terjadi jika daftar dibuat pada ukuran default. Menurut tim analisis kinerja kami, sekitar 85% instans ArrayList dibuat dalam ukuran default sehingga pengoptimalan ini akan valid untuk sebagian besar kasus.
Untuk HashMap, penggunaan materi iklan dibuat dari bidang ambang batas untuk melacak ukuran awal yang diminta hingga susunan keranjang diperlukan. Di sisi baca, kasus peta kosong diuji dengan isEmpty (). Pada ukuran tulis, perbandingan (table == EMPTY_TABLE) digunakan untuk mendeteksi kebutuhan untuk memekarkan larik keranjang. Di readObject ada sedikit pekerjaan lagi untuk mencoba memilih kapasitas awal yang efisien.
Dari: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-April/015585.html
getCapacity()
metode, atau semacamnya. (Yang mengatakan, sesuatu sepertiensureCapacity(7)
adalah tidak ada operasi untuk ArrayList yang diinisialisasi default, jadi saya kira kita benar-benar harus bertindak seolah-olah kapasitas awalnya benar-benar 10 ...)ArrayList
dibuat dengan konstruktor no-arg vs meneruskan nol keint
konstruktor, dan jika Anda melihat ukuran larik internal secara reflektif atau dalam debugger. Dalam kasus default, larik melompat dari panjang 0 ke 10, lalu ke 15, 22, mengikuti tingkat pertumbuhan 1,5x. Melewati nol sebagai hasil kapasitas awal dalam pertumbuhan dari 0 ke 1, 2, 3, 4, 6, 9, 13, 19 ....emptyList()
masih mengkonsumsi lebih sedikit memori daripada beberapaArrayList
instance kosong . Ini hanya kurang penting sekarang dan karenanya tidak diperlukan di setiap tempat, terutama tidak di tempat dengan kemungkinan lebih tinggi untuk menambahkan elemen di lain waktu. Juga perlu diingat bahwa Anda terkadang menginginkan daftar kosong yang tidak dapat diubah dan kemudianemptyList()
adalah cara untuk pergi.Di java 8, kapasitas default ArrayList adalah 0 hingga kami menambahkan setidaknya satu objek ke objek ArrayList (Anda dapat menyebutnya inisialisasi malas).
Sekarang pertanyaannya adalah mengapa perubahan ini dilakukan di JAVA 8?
Jawabannya adalah untuk menghemat konsumsi memori. Jutaan objek daftar larik dibuat dalam aplikasi java waktu nyata. Ukuran default 10 objek berarti kita mengalokasikan 10 pointer (40 atau 80 byte) untuk array yang mendasari saat pembuatan dan mengisinya dengan null. Array kosong (diisi dengan nulls) menempati banyak memori.
Inisialisasi malas menunda konsumsi memori ini sampai Anda benar-benar akan menggunakan daftar array.
Silakan lihat kode di bawah ini untuk bantuan.
Artikel Kapasitas default ArrayList di Java 8 menjelaskannya secara detail.
sumber
Jika operasi pertama yang dilakukan dengan ArrayList adalah meneruskan
addAll
koleksi yang memiliki lebih dari sepuluh elemen, maka segala upaya yang dilakukan untuk membuat larik sepuluh elemen awal untuk menampung konten ArrayList akan dibuang ke luar jendela. Kapan pun sesuatu ditambahkan ke ArrayList, perlu untuk menguji apakah ukuran daftar yang dihasilkan akan melebihi ukuran penyimpanan dukungan; mengizinkan penyimpanan cadangan awal untuk memiliki ukuran nol daripada sepuluh akan menyebabkan pengujian ini gagal satu kali ekstra selama masa aktif daftar yang operasi pertamanya adalah "tambah" yang akan memerlukan pembuatan larik sepuluh item awal, tetapi biayanya adalah kurang dari biaya pembuatan larik sepuluh item yang tidak akan pernah digunakan.Seperti yang telah dikatakan, mungkin saja untuk meningkatkan kinerja lebih jauh dalam beberapa konteks jika ada kelebihan "addAll" yang menentukan berapa banyak item (jika ada) yang kemungkinan akan ditambahkan ke daftar setelah yang ada, dan mana yang dapat gunakan itu untuk mempengaruhi perilaku alokasinya. Dalam beberapa kasus, kode yang menambahkan beberapa item terakhir ke daftar akan memiliki gagasan yang cukup bagus bahwa daftar tidak akan pernah membutuhkan spasi lebih dari itu. Ada banyak situasi di mana daftar akan diisi satu kali dan tidak pernah diubah setelah itu. Jika pada kode poin mengetahui bahwa ukuran akhir dari sebuah daftar adalah 170 elemen, ia memiliki 150 elemen dan penyimpanan pendukung berukuran 160,
sumber
addAll()
. Itu adalah kesempatan lain untuk meningkatkan efisiensi di sekitar malloc pertama.Pertanyaannya adalah 'mengapa?'.
Pemeriksaan profil memori (misalnya ( https://www.yourkit.com/docs/java/help/inspections_mem.jsp#sparse_arrays ) menunjukkan bahwa array kosong (diisi dengan nulls) menempati banyak memori.
Ukuran default 10 objek berarti kita mengalokasikan 10 pointer (40 atau 80 byte) untuk array yang mendasari saat pembuatan dan mengisinya dengan null. Aplikasi java nyata membuat jutaan daftar array.
Modifikasi yang diperkenalkan menghapus ^ W menunda konsumsi memori ini sampai Anda benar-benar akan menggunakan daftar larik.
sumber
Setelah pertanyaan di atas saya pergi melalui ArrayList Document of Java 8. Saya menemukan ukuran default masih 10 saja.
sumber
Ukuran default ArrayList di JAVA 8 adalah stil 10. Satu-satunya perubahan yang dibuat di JAVA 8 adalah jika pembuat kode menambahkan elemen kurang dari 10 maka tempat kosong daftar array yang tersisa tidak ditentukan ke null. Mengatakan demikian karena saya sendiri telah melalui situasi ini dan gerhana membuat saya melihat perubahan JAVA 8 ini.
Anda dapat membenarkan perubahan ini dengan melihat tangkapan layar di bawah ini. Di dalamnya Anda dapat melihat bahwa ukuran ArrayList ditentukan sebagai 10 di Object [10] tetapi jumlah elemen yang ditampilkan hanya 7. Elemen nilai null lainnya tidak ditampilkan di sini. Di JAVA 7, screenshot di bawah ini sama dengan hanya satu perubahan yaitu elemen nilai null juga ditampilkan di mana pembuat kode perlu menulis kode untuk menangani nilai null jika dia mengulang daftar array lengkap sementara di JAVA 8 beban ini dihapus dari kepala pembuat kode / pengembang.
Tautan tangkapan layar.
sumber