hello! Kuliah hari ini
ArrayList
, di satu pihak, lebih mudah, dan di sisi lain, lebih sukar daripada yang sebelumnya. Ia lebih sukar, kerana hari ini kita akan melihat "di bawah tudung" ArrayList
dan mengkaji apa yang berlaku padanya semasa operasi. Sebaliknya, hampir tiada kod dalam kuliah ini - kebanyakannya gambar dan penerangan. Jadi, mari kita pergi :) Seperti yang anda sedia maklum, di dalam ArrayList
'a terdapat tatasusunan biasa, yang bertindak sebagai stor data. Dalam kebanyakan kes, kami tidak menyatakan saiz senarai yang tepat. Tetapi tatasusunan dalaman mesti mempunyai beberapa saiz! Ini adalah benar. Saiz lalainya ialah [10] .
public static void main(String[] args) {
ArrayList<Car> cars = new ArrayList<>();
}
Mula-mula, mari kita lihat rupa penambahan elemen baharu. Pertama sekali, semakan dibuat untuk melihat sama ada terdapat ruang yang mencukupi dalam tatasusunan dalaman dan sama ada satu elemen lagi akan muat. Jika terdapat ruang, elemen baharu akan ditambahkan pada penghujung senarai. Apabila kami menyebut "hingga akhir", kami tidak bermaksud sel terakhir tatasusunan (itu akan menjadi pelik). Ini merujuk kepada sel di sebelah elemen semasa yang terakhir. Indeksnya akan sama dengan cars.size()
. Senarai kami pada masa ini kosong ( cars.size() = 0
). Sehubungan itu, elemen baharu akan ditambah pada sel dengan indeks 0
.
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
cars.add(ferrari);
Semuanya jelas di sini. Apakah yang akan berlaku jika sisipan dijalankan di tengah, iaitu antara beberapa elemen?
public static void main(String[] args) {
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
Car bugatti = new Car("Bugatti Veyron");
Car lambo = new Car("Lamborghini Diablo");
Car ford = new Car("Ford Modneo");
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
cars.add(1, ford);//добавляем ford в ячейку 1, которая уже занята
}
Sekali lagi, ia mula-mula menyemak untuk melihat sama ada terdapat ruang yang mencukupi dalam tatasusunan. Sekiranya terdapat ruang yang mencukupi, elemen dialihkan ke kanan bermula dari sel tempat kita memasukkan elemen baharu. Kami menampal ke dalam sel dengan indeks 1. Iaitu, elemen dari sel 3 disalin ke sel 4, elemen 2 ke sel 3, elemen 1 ke sel 2. Selepas itu, elemen baharu kami ditampal pada tempatnya. Elemen sebelumnya ( bugatti
) telah pun disalin dari sana ke lokasi baharu. Sekarang mari kita fikirkan bagaimana proses ini akan berlaku jika tiada ruang untuk memasukkan dalam tatasusunan. Pertama, sudah tentu, semakan dibuat untuk melihat sama ada terdapat ruang yang mencukupi. Jika ternyata ruang tidak mencukupi, ArrayList
tatasusunan saiz baharu (saiz OldArray * 1.5) + 1 dicipta di dalam 'a. Dalam kes kami, tatasusunan baharu akan mempunyai saiz 16 sel. Semua elemen semasa akan disalin di sana serta-merta. Tatasusunan lama akan dipadamkan oleh pemungut sampah, dan hanya tatasusunan baharu yang dikembangkan akan kekal. Kini terdapat ruang kosong untuk elemen baharu. Kami menampalnya ke dalam sel 3, yang telah diduduki. Sekarang prosedur biasa bermula. Semua elemen bermula pada indeks 3 dialihkan satu sel ke kanan, dan elemen baharu ditambah secara senyap. Dan kini sisipan berjaya! Kami menyelesaikan sisipan. Sekarang mari kita bincangkan tentang mengalih keluar elemen . Seperti yang anda ingat, apabila bekerja dengan tatasusunan, kami menghadapi masalah: apabila kami memadamkannya, "lubang" kekal di dalamnya. Satu-satunya penyelesaian ialah mengalihkan elemen ke kiri setiap kali ia dipadamkan, dan anda perlu menulis kod untuk peralihan itu sendiri. ArrayList
berfungsi pada prinsip yang sama, tetapi di dalamnya mekanisme ini telah dilaksanakan secara automatik. Beginilah rupanya: Dan akhirnya kita mendapat hasil yang diingini: Elemen lambo
telah berjaya dipadamkan. Di sini kami melakukan penyingkiran dari tengah. Adalah jelas bahawa pemadaman dari penghujung senarai akan menjadi lebih cepat, kerana elemen yang dikehendaki dialih keluar tanpa mengalihkan semua yang lain. Mari kita lihat lagi saiz tatasusunan dalaman dan storannya dalam ingatan. Pengembangan tatasusunan ialah proses yang mengambil sejumlah sumber. Oleh itu, anda tidak seharusnya membuat ArrayList
dengan saiz lalai jika anda tahu pasti bahawa ia akan mempunyai sekurang-kurangnya 100 elemen. Pada masa anda dapat memasukkan elemen ke-100, tatasusunan dalaman akan berkembang 6 kali ganda , setiap kali memindahkan semua elemen.
- daripada 10 elemen kepada 16
- daripada 16 elemen kepada 25
- dari 25 hingga 38
- dari 38 hingga 58
- dari 58 hingga 88
- dari 88 hingga 133 (mengikut formula (saiz Array Lama * 1.5) + 1)
ArrayList<Car> cars = new ArrayList<>(100);
Kini susunan 100 elemen akan segera diperuntukkan dalam ingatan, yang akan menjadi lebih cekap kerana sumber tidak akan dibazirkan untuk pengembangan. Terdapat juga bahagian lain syiling. Apabila objek dialih keluar daripada ArrayList
tatasusunan dalaman, saiznya tidak dikurangkan secara automatik. Sebagai contoh, kami mempunyai ArrayList
tatasusunan dalaman 88 elemen, yang diisi sepenuhnya: Semasa operasi program, kami mengeluarkan 77 elemen daripadanya, dan hanya 11 kekal di dalamnya: Adakah anda sudah meneka apa masalahnya? Penggunaan memori yang tidak cekap, sudah tentu! Kami menggunakan hanya 11 sel, sementara kami mempunyai memori yang diperuntukkan untuk 88 elemen - itu 8 kali lebih banyak daripada yang kami perlukan! Untuk menjalankan pengoptimuman dalam kes ini, anda boleh menggunakan kaedah kelas khas ArrayList
- trimToSize()
. Ia "memotong" panjang tatasusunan dalaman kepada bilangan elemen yang sedang disimpan di dalamnya. Kini sebanyak memori diperuntukkan mengikut keperluan! :)
GO TO FULL VERSION