Baru-baru ini saya melihat deskripsi yang sangat bagus tentang kerangka koleksi di buku J2EE, saya memfilternya dan mempostingnya untuk dibagikan kepada semua orang. Kerangka koleksi menyediakan antarmuka dan kelas untuk mengelola koleksi objek berikut penjelasan masing-masing komponennya.
Antarmuka koleksi
Koleksi adalah antarmuka koleksi paling dasar. Koleksi mewakili sekumpulan Objek, yaitu elemen Koleksi. Beberapa Koleksi mengizinkan elemen yang identik dan yang lainnya tidak. Ada yang semacam dan ada yang tidak. Java SDK tidak menyediakan kelas yang mewarisi langsung dari Koleksi. Kelas yang disediakan oleh Java SDK semuanya merupakan "sub-antarmuka" yang mewarisi dari Koleksi, seperti Daftar dan Set.
Semua kelas yang mengimplementasikan antarmuka Koleksi harus menyediakan dua konstruktor standar: konstruktor tanpa parameter untuk membuat Koleksi kosong, dan konstruktor parameter Koleksi untuk membuat Koleksi baru. Koleksi masukan memiliki elemen yang sama. Konstruktor terakhir memungkinkan pengguna untuk menyalin Koleksi.
Bagaimana cara mengulangi setiap elemen dalam Koleksi? Terlepas dari tipe Koleksi sebenarnya, ini mendukung metode iterator(), yang mengembalikan iterator yang dapat digunakan untuk mengakses setiap elemen dalam Koleksi satu per satu. Penggunaan umumnya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
Iterator it = collection.iterator(); // Dapatkan iterator
while(it.hasNext()) {
Objek obj = it.next(); // Dapatkan elemen selanjutnya
}
Dua antarmuka yang berasal dari antarmuka Koleksi adalah Daftar dan Set.
Antarmuka daftar Daftar adalah Koleksi yang diurutkan. Dengan menggunakan antarmuka ini, Anda dapat mengontrol posisi penyisipan setiap elemen dengan tepat. Pengguna dapat mengakses elemen dalam Daftar menggunakan indeks (posisi elemen dalam Daftar, mirip dengan subskrip array), yang mirip dengan array Java.
Berbeda dengan Set yang disebutkan di bawah, List mengizinkan elemen yang sama.
Selain metode iterator() yang diperlukan untuk antarmuka Koleksi, List juga menyediakan metode listIterator(), yang mengembalikan antarmuka ListIterator, Dibandingkan dengan antarmuka Iterator standar, ListIterator memiliki lebih banyak add() dan metode lainnya, yang memungkinkan penambahan. Hapus, atur elemen, dan lintasi maju atau mundur.
Kelas umum yang mengimplementasikan antarmuka Daftar adalah LinkedList, ArrayList, Vector dan Stack.
kelas LinkedList LinkedList mengimplementasikan antarmuka Daftar dan mengizinkan elemen nol. Selain itu, LinkedList menyediakan metode dapatkan, hapus, dan sisipkan tambahan di bagian awal atau akhir LinkedList. Operasi ini memungkinkan LinkedList digunakan sebagai tumpukan, antrian, atau deque.
Perhatikan bahwa LinkedList tidak memiliki metode yang disinkronkan. Jika beberapa thread mengakses Daftar secara bersamaan, mereka harus menerapkan sinkronisasi akses sendiri. Salah satu solusinya adalah dengan membuat Daftar yang disinkronkan saat membuat Daftar:
Daftar daftar = Koleksi.synchronizedList(new LinkedList(...));
kelas Daftar Array ArrayList mengimplementasikan array berukuran variabel. Ini mengizinkan semua elemen, termasuk null. ArrayList tidak disinkronkan.
Waktu berjalan metode size, isEmpty, get, dan set adalah konstan. Namun, biaya metode penjumlahan merupakan konstanta diamortisasi, dan penambahan n elemen memerlukan waktu O(n). Metode lain memiliki waktu berjalan linier.
Setiap instance ArrayList memiliki kapasitas (Capacity), yaitu ukuran array yang digunakan untuk menyimpan elemen. Kapasitas ini meningkat secara otomatis seiring dengan penambahan elemen baru, namun algoritma pertumbuhannya tidak ditentukan. Ketika sejumlah besar elemen perlu dimasukkan, metode sureCapacity dapat dipanggil untuk meningkatkan kapasitas ArrayList sebelum memasukkan guna meningkatkan efisiensi penyisipan.
Seperti LinkedList, ArrayList juga tidak disinkronkan.
Kelas vektor Vektor sangat mirip dengan ArrayList, tetapi Vektor disinkronkan. Meskipun Iterator yang dibuat oleh Vector memiliki antarmuka yang sama dengan Iterator yang dibuat oleh ArrayList, karena Vector disinkronkan, ketika Iterator dibuat dan digunakan, thread lain mengubah status Vector (misalnya, menambah atau menghapus beberapa elemen) , ConcurrentModificationException akan dilempar saat memanggil metode Iterator, jadi pengecualian harus ditangkap.
Kelas tumpukan Stack mewarisi dari Vector dan mengimplementasikan tumpukan last-in-first-out. Stack menyediakan 5 metode tambahan yang memungkinkan Vector digunakan sebagai stack. Metode dasar push dan pop, serta metode mengintip, menempatkan elemen di bagian atas tumpukan, metode kosong menguji apakah tumpukan kosong, dan metode pencarian mendeteksi posisi elemen dalam tumpukan. Stack adalah tumpukan kosong setelah dibuat.
Atur antarmuka Set adalah Koleksi yang tidak mengandung elemen duplikat, yaitu dua elemen e1 dan e2 memiliki e1.equals(e2)=false, dan Set memiliki paling banyak satu elemen null.
Jelasnya, konstruktor Set memiliki batasan bahwa parameter Koleksi yang diteruskan tidak boleh berisi elemen duplikat.
Harap diperhatikan: Objek yang Dapat Diubah harus ditangani dengan hati-hati. Jika elemen yang bisa berubah dalam suatu Set mengubah statusnya sehingga menyebabkan Object.equals(Object)=true, hal itu akan menyebabkan beberapa masalah.
Antarmuka peta <BR>Harap diperhatikan bahwa Peta tidak mewarisi antarmuka Koleksi. Peta menyediakan kunci untuk pemetaan nilai. Peta tidak boleh berisi kunci yang sama, dan setiap kunci hanya dapat memetakan satu nilai. Antarmuka Peta menyediakan tiga jenis tampilan kumpulan. Isi Peta dapat dianggap sebagai kumpulan kumpulan kunci, kumpulan kumpulan nilai, atau kumpulan pemetaan nilai kunci.
Kelas hashtable Hashtable mewarisi antarmuka Peta dan mengimplementasikan tabel hash pemetaan nilai kunci. Objek apa pun yang bukan nol dapat digunakan sebagai kunci atau nilai.
Untuk menambahkan data, gunakan put(key, value), dan untuk menghapus data, gunakan get(key). Biaya waktu dari kedua operasi dasar ini adalah konstan.
Hashtable menyesuaikan kinerja melalui dua parameter: kapasitas awal dan faktor beban. Biasanya faktor beban default 0,75 mencapai keseimbangan yang lebih baik antara waktu dan ruang. Meningkatkan faktor muatan dapat menghemat ruang namun waktu pencarian terkait akan meningkat, yang akan memengaruhi operasi seperti ambil dan letakkan.
Contoh sederhana penggunaan Hashtable adalah sebagai berikut. Masukkan 1, 2, dan 3 ke dalam Hashtable, dan kuncinya masing-masing adalah "satu", "dua", dan "tiga":
Copy kode kodenya sebagai berikut:
Nomor Hashtable = Hashtable baru();
angka.put("satu", Integer baru(1));
angka.put("dua", Integer baru(2));
angka.put("tiga", Integer baru(3));
Untuk mengambil nomor, misalnya 2, gunakan tombol yang sesuai:
Bilangan bulat n = (Bilangan Bulat)angka.get(“dua”);
System.out.println(“dua = ” + n);
Karena objek yang digunakan sebagai kunci akan menentukan posisi nilai terkait dengan menghitung fungsi hashnya, objek apa pun yang digunakan sebagai kunci harus mengimplementasikan metode kode hash dan sama dengan. Metode hashCode dan same dengan yang diwarisi dari kelas root Object. Jika Anda menggunakan kelas khusus sebagai kunci, berhati-hatilah. Menurut definisi fungsi hash, jika kedua objek itu sama, yaitu obj1.equals( obj2)=true, maka kode hashnya harus sama, tetapi jika dua objek berbeda, kode hashnya belum tentu berbeda. Jika kode hash dari dua objek berbeda sama, fenomena ini disebut konflik waktu overhead pengoperasian tabel hash meningkat. Oleh karena itu, cobalah untuk mendefinisikan metode hashCode() yang terdefinisi dengan baik untuk mempercepat operasi tabel hash.
Jika objek yang sama memiliki kode hash yang berbeda, pengoperasian tabel hash akan memberikan hasil yang tidak diharapkan (metode get yang diharapkan mengembalikan null). Untuk menghindari masalah ini, Anda hanya perlu mengingat satu hal: ganti metode sama dengan dan metode kode hash secara bersamaan waktu. Jangan menulis hanya satu saja.
Hashtable sinkron.
kelas HashMap HashMap mirip dengan Hashtable, hanya saja HashMap tidak sinkron dan mengizinkan null, yaitu nilai null dan kunci null. , tetapi ketika memperlakukan HashMap sebagai Koleksi (metode nilai () dapat mengembalikan Koleksi), overhead waktu dari sub-operasi iterasinya sebanding dengan kapasitas HashMap. Oleh karena itu, jika kinerja operasi berulang sangat penting, jangan atur kapasitas awal HashMap terlalu tinggi atau faktor beban terlalu rendah.
Kelas HashMap yang lemah WeakHashMap adalah HashMap yang ditingkatkan yang mengimplementasikan "referensi lemah" ke kunci. Jika kunci tidak lagi direferensikan secara eksternal, kunci tersebut dapat didaur ulang oleh GC.
Ringkasan <BR>Jika melibatkan operasi seperti tumpukan dan antrian, Anda harus mempertimbangkan untuk menggunakan Daftar. Jika Anda perlu menyisipkan dan menghapus elemen dengan cepat, Anda harus menggunakan LinkedList. Jika Anda memerlukan akses acak cepat ke elemen, Anda harus menggunakan ArrayList.
Jika program berada dalam lingkungan thread tunggal, atau akses hanya dilakukan di satu thread, pertimbangkan kelas asinkron, yang lebih efisien. Jika beberapa thread dapat mengoperasikan suatu kelas pada saat yang sama, kelas yang disinkronkan harus digunakan.
Berikan perhatian khusus pada pengoperasian tabel hash. Objek yang digunakan sebagai kunci harus mengganti metode sama dengan dan kode hash dengan benar.
Cobalah untuk mengembalikan antarmuka daripada tipe sebenarnya, seperti mengembalikan Daftar alih-alih ArrayList, sehingga jika Anda perlu mengganti ArrayList dengan LinkedList di masa mendatang, kode klien tidak perlu diubah. Ini adalah pemrograman untuk abstraksi.