1. Gambaran keseluruhan
Untuk koleksi, perpustakaan standard Java menyediakan banyak pilihan untuk dipilih. Antara pilihan tersebut adalah dua pelaksanaan List yang terkenal yang dikenali sebagai ArrayList dan LinkedList, masing-masing mempunyai sifat dan kes penggunaan mereka sendiri.
Dalam tutorial ini, kita akan melihat bagaimana kedua-duanya sebenarnya dilaksanakan. Kemudian, kami akan menilai aplikasi yang berbeza untuk setiap aplikasi.
2. ArrayList
Secara dalaman, ArrayList menggunakan array untuk melaksanakan antara muka List . Oleh kerana tatasusunan berukuran tetap di Java, ArrayList membuat array dengan beberapa kapasiti awal. Sepanjang perjalanan, jika kita perlu menyimpan lebih banyak item daripada kapasiti lalai, ia akan menggantikan susunan itu dengan yang baru dan lebih luas.
Untuk lebih memahami sifatnya, mari kita menilai struktur data ini berkenaan dengan tiga operasi utamanya: menambah item, mendapatkan satu mengikut indeks dan mengeluarkan mengikut indeks.
2.1. Tambah
Semasa kami membuat ArrayList kosong , ia memulakan array penyokongnya dengan kapasiti lalai (saat ini 10):

Menambah item baru sementara array itu belum penuh semudah menetapkan item itu ke indeks array tertentu. Indeks tatasusunan ini ditentukan oleh ukuran tatasusunan semasa kerana secara praktikal kami menambahkan senarai:
backingArray[size] = newItem; size++;
Jadi, dalam kes terbaik dan rata-rata, kerumitan masa untuk operasi tambah adalah O (1) , yang cukup pantas. Oleh kerana array sokongan menjadi penuh, pelaksanaan add menjadi kurang cekap:

Untuk menambahkan item baru, pertama-tama kita harus memulakan array baru dengan lebih banyak kapasiti dan menyalin semua item yang ada ke array baru. Hanya setelah menyalin elemen semasa kita dapat menambahkan item baru. Oleh itu, kerumitan masa adalah O (n) dalam keadaan terburuk kerana kita harus menyalin unsur n terlebih dahulu.
Secara teori, menambahkan elemen baru berjalan dalam masa tetap yang dilunaskan. Iaitu, menambahkan unsur n memerlukan masa O (n) . Walau bagaimanapun, beberapa penambahan tunggal mungkin tidak berfungsi dengan baik kerana salinannya terlalu banyak.
2.2. Akses mengikut Indeks
Mengakses item mengikut indeksnya adalah tempat ArrayList benar-benar bersinar. Untuk mendapatkan item di indeks i, kita hanya perlu mengembalikan item yang berada di indeks ith dari array sokongan. Akibatnya, kerumitan waktu untuk akses oleh operasi indeks selalu O (1).
2.3. Keluarkan mengikut Indeks
Katakan kita akan mengeluarkan indeks 6 dari ArrayList kami , yang sesuai dengan elemen 15 dalam susunan sokongan kami:

Setelah menandakan elemen yang diinginkan sebagai dihapus, kita harus memindahkan semua elemen setelahnya kembali dengan satu indeks. Jelasnya, semakin dekat elemen pada permulaan array, semakin banyak elemen yang harus kita gerakkan. Jadi kerumitan masa adalah O (1) pada kes terbaik dan O (n) rata-rata dan kes terburuk.
2.4. Aplikasi dan Batasan
Biasanya, ArrayList adalah pilihan lalai untuk banyak pemaju apabila mereka memerlukan Senarai pelaksanaan. Sebenarnya, ini sebenarnya pilihan yang masuk akal apabila jumlah pembacaannya jauh lebih banyak daripada jumlah penulisan .
Kadang kala kita memerlukan pembacaan dan penulisan yang sama. Sekiranya kita mempunyai anggaran jumlah maksimum item yang mungkin, maka masih masuk akal untuk menggunakan ArrayList . Sekiranya demikian, kita dapat memulakan ArrayList dengan kapasiti awal:
int possibleUpperBound = 10_000; List items = new ArrayList(possibleUpperBound);
Anggaran ini dapat mengelakkan banyak penyalinan dan peruntukan array yang tidak perlu.
Lebih-lebih lagi, array diindeks oleh nilai int di Java. Oleh itu, tidak mungkin menyimpan lebih daripada 232 elemen dalam larik Java dan, oleh itu, dalam ArrayList .
3. Senarai Terpaut
LinkedList , seperti namanya, menggunakan koleksi nod terpaut untuk menyimpan dan mengambil elemen . Sebagai contoh, inilah cara pelaksanaan Java setelah menambahkan empat elemen:

Setiap nod mengekalkan dua titik: satu menunjuk ke elemen seterusnya dan satu lagi merujuk kepada yang sebelumnya. Dengan memperluas ini, senarai berganda yang mempunyai dua petunjuk menunjukkan item pertama dan terakhir.
Sekali lagi, mari kita menilai pelaksanaan ini berkenaan dengan operasi asas yang sama.
3.1. Tambah
Untuk menambahkan simpul baru, pertama, kita harus menghubungkan simpul terakhir semasa ke nod baru:

Dan kemudian kemas kini penunjuk terakhir:

Oleh kerana kedua-dua operasi ini sepele, kerumitan masa untuk operasi tambah selalu O (1) .
3.2. Akses mengikut Indeks
LinkedList, berbanding ArrayList, tidak menyokong akses rawak cepat. Oleh itu, untuk mencari elemen mengikut indeks, kita harus melintasi beberapa bahagian senarai secara manual .
Dalam kes yang terbaik, apabila item yang diminta hampir pada awal atau akhir senarai, kerumitan waktu akan secepat O (1). Namun, dalam senario purata dan terburuk, kita mungkin berakhir dengan masa akses O (n) kerana kita harus memeriksa banyak nod satu demi satu.
3.3. Keluarkan mengikut Indeks
Untuk membuang item, pertama-tama kita harus mencari item yang diminta dan kemudian membatalkan pautan dari senarai . Akibatnya, masa akses menentukan kerumitan waktu - iaitu, O (1) pada keadaan terbaik dan O (n) secara purata dan dalam senario terburuk.
3.4. Permohonan
LinkedLists lebih sesuai apabila kadar penambahan jauh lebih tinggi daripada kadar baca .
Juga, ia boleh digunakan dalam senario baca-berat ketika kebanyakan masa kita mahukan elemen pertama atau terakhir. Perlu disebutkan bahawa LinkedList juga menerapkan antara muka Deque - menyokong akses yang cekap ke kedua-dua hujung koleksi.
Secara umum, jika kita mengetahui perbezaan pelaksanaannya, maka kita dapat memilihnya dengan mudah untuk kasus penggunaan tertentu.
Sebagai contoh, katakan bahawa kita akan menyimpan banyak acara siri masa dalam struktur data seperti senarai. Kami tahu bahawa kami akan menerima ledakan acara setiap saat.
Juga, kita perlu memeriksa semua peristiwa satu demi satu secara berkala dan memberikan beberapa statistik. Untuk kes penggunaan ini, LinkedList adalah pilihan yang lebih baik kerana kadar penambahan jauh lebih tinggi daripada kadar baca.
Juga, kami akan membaca semua item, jadi kami tidak dapat mengalahkan batas atas O (n) .
4. Kesimpulan
Dalam tutorial ini, pertama, kami menyelidiki bagaimana ArrayList dan LinkLists dilaksanakan di Java.
Kami juga menilai kes penggunaan yang berbeza untuk masing-masing.