Set di Java adalah set yang tidak mengandung elemen duplikat, atau tepatnya, pasangan elemen yang tidak mengandung e1.Equals (E2). NULL diizinkan di set. Set tidak dapat menjamin urutan elemen di set.
Saat menambahkan elemen untuk mengatur, jika elemen yang ditentukan tidak ada, penambahan berhasil. Artinya, jika elemen E1 tidak ada di set (E == NULL? E1 == NULL: E.QUEALS (E1)), maka E1 dapat ditambahkan ke set.
Berikut adalah hashset kelas implementasi yang ditetapkan sebagai contoh, dan secara singkat memperkenalkan prinsip set untuk tidak mengulangi implementasi:
Paket com.darren.test.overide; kelas publik customString {private string value; customString publik () {this ("");} customString publik (nilai string) {this.value = value;}} Paket com.darren.test.overide; import java.util.hashset; import java.util.set; kelas publik hashSettest {public static void main (string [] args) {string a = new string ("a"); string b = new string ("a"); customstring c = new customstring ("b" new string ("a"); customstring c = new customstring ("b" new string ("a"); customstring c = new customstring ("b" new string ("a"); customstring c = new customString ("b" new string ("a"); customstring c = new customString ("B"); CustomString ("B"); System.out.println ("A.Equals (b) ==" + a.equals (b)); System.out.println ("C.Equals (D) ==" + C.Equals (D)); set <bestigasi> set = set = baru Hashset <Papen> (); set.add (a); set.add (b); set.add (c); set.add (d); System.out.println ("set.size () ==" + set.size ()); untuk (objek objek: set) {System.out.println (object);Hasil operasi adalah sebagai berikut:
A.Equals (b) == true c.equals (d) == false set.size () == 3 com.darren.test.overide.customstring@2c39d2 a com.darren.test.overide.customstring@5795ce
Mungkin Anda telah melihat kuncinya, benar, itu metode yang sama. Masih tidak pantas untuk mengatakan ini, tetapi tepatnya, itu harus menjadi metode kode yang setara dan hash. Mengapa Anda mengatakan itu? Mari ubah kelas CustomString dan uji:
package com.darren.test.overide;public class CustomString {private String value;public CustomString() {this("");}public CustomString(String value) {this.value = value;}@Override public Boolean equals(Object obj) {if (this == obj) {return true;} else if (obj instanceof CustomString) {CustomString customString = (CustomString) obj; return customstring.value.equals (value);} else {return false;}}}Hasil tes:
A.Equals (b) == true c.equals (d) == true set.size () == 3 com.darren.test.overide.customstring@12504e0 a com.darren.test.overide.customstring@1630eb6
Nilai pengembalian sama kali ini benar, tetapi ukuran set masih 3.
Mari terus berubah
Paket com.darren.test.overide; kelas publik CustomString {private string value; public CustomString () {this ("");} public CustomString (nilai string) {this.value = value;}@override public int hashCode () {// return super.hashcode (); return 1;}}Lihatlah hasilnya lagi:
A.Equals (b) == true c.equals (d) == false set.size () == 3 com.darren.test.overide.customstring@1 com.darren.test.overide.customstring@1 a
Hanya menulis ulang metode kode hash, juga tidak menulis ulang metode yang sama
Akhirnya, ubah
package com.darren.test.overide;public class CustomString {private String value;public CustomString() {this("");}public CustomString(String value) {this.value = value;}@Override public Boolean equals(Object obj) {if (this == obj) {return true;} else if (obj instanceof CustomString) {CustomString customString = (CustomString) obj; return customString.Value.Equals (value);} else {return false;}}@override public int hashCode () {// return super.hashcode (); return 1;}}Hasil akhir:
A.Equals (b) == true c.equals (d) == true set.size () == 2 com.darren.test.overide.customstring@1 a
OK, terbukti bahwa Anda perlu menulis ulang metode Equals dan HashCode, dan melihat prinsipnya:
Konvensi untuk kode hash di java.lnag.object:
1. Selama eksekusi aplikasi, jika informasi yang digunakan untuk membandingkan metode setara suatu objek tidak dimodifikasi, metode kode hash disebut beberapa kali pada objek, dan harus secara konsisten mengembalikan bilangan bulat yang sama.
2. Jika kedua objek tersebut sama sesuai dengan metode yang setara (Objecto), memanggil metode kode hashcode dari salah satu dari dua objek harus menghasilkan hasil integer yang sama.
3. Jika kedua objek tidak sama sesuai dengan metode yang setara (Objecto), maka metode kode hashcode dari salah satu dari dua objek dipanggil, dan tidak diperlukan hasil integer yang berbeda. Tetapi jika itu bisa berbeda, itu dapat meningkatkan kinerja tabel hash.
Dalam hashset, operasi dasar diimplementasikan oleh lapisan hashmap, karena lapisan hashset menggunakan hashmap untuk menyimpan data. Saat menambahkan elemen ke hashset, pertama -tama hitung nilai kode hashcode elemen, dan kemudian gunakan ini (kode hash dari elemen)% (ukuran pengumpulan hashmap) + 1 untuk menghitung lokasi penyimpanan elemen ini. Jika posisi ini kosong, tambahkan elemen; Jika tidak kosong, gunakan metode Equals untuk membandingkan apakah elemennya sama, dan jika sama sama, jangan menambahkannya, jika tidak temukan ruang kosong untuk menambahkannya.
Berikut ini adalah bagian dari kode sumber hashset:
Paket java.util; hashset kelas publik <e> memperluas abstrakset <e> mengimplementasikan set <e>, klonable, java.io.serializable {static final long serialversionuid = -502474406713321676l; // Lapisan yang kurang memanfaatkan. Hashmap transien pribadi <e, objek> peta; // Tentukan objek objek virtual sebagai nilai hashmap, dan tentukan objek ini sebagai final statis. Private Static Final Object Present = New Object ();/*** Konstruktor tanpa parameter default membangun hashset kosong. * * Faktanya, lapisan yang mendasarinya akan menginisialisasi hashmap kosong dan menggunakan kapasitas awal default 16 dan faktor pemuatan 0,75. */hashset publik () {peta = hashmap baru <e, objek> ();}/*** Bangun set baru yang berisi elemen dalam koleksi yang ditentukan. * * Lapisan yang mendasari aktual menggunakan faktor beban default 0,75 dan cukup untuk mengandung kapasitas awal semua elemen dalam koleksi * yang ditentukan untuk membuat hashmap. * @param c Elemen di dalamnya akan disimpan dalam koleksi di set ini. */hashset publik (koleksi <extends e> c) {map = hashmap baru <e, objek> (math.max ((int) (c.size ()/. 75f) + 1, 16)); addall (c);}/*** Bangun hashset kosong dengan kapasitas inisial dan beban yang ditentukan. * * Lapisan yang mendasarinya membuat hashmap kosong dengan parameter yang sesuai. * @param Kapasitas Awal Kapasitas Awal. * @param LoadFactor Load Factor. */hashset publik (int initialcapacity, float loadFactor) {MAP = hashmap baru <e, objek> (InitialCapacity, loadFactor);}/*** Bangun hashset kosong dengan kapasitas inisial yang ditentukan. * * Faktanya, lapisan yang mendasarinya membangun hashmap kosong dengan parameter yang sesuai dan faktor beban beban 0,75. * @param Kapasitas Awal Kapasitas Awal. */hashset publik (int initialcapacity) {MAP = new HashMap <e, objek> (initialCapacity);}/*** Bangun koleksi hash tautan kosong baru dengan kapasitas inisial dan loadFactor yang ditentukan. * Konstruktor ini adalah izin akses paket dan tidak terpapar kepada publik. Ini sebenarnya hanya dukungan untuk LinkedHashset. * * Faktanya, lapisan yang mendasarinya akan membangun instance LinkedHashMap kosong dengan parameter yang ditentukan untuk mengimplementasikannya. * @param Kapasitas Awal Kapasitas Awal. * @param LoadFactor Load Factor. * @param Dummy Tag. */Hashset (int initialcapacity, float loadfactor, boolean dummy) {map = new LinkedHashMap <e, objek> (InitialCapacity, LoadFactor);}/*** Mengembalikan iterator yang mengulangi elemen dalam set ini. Urutan elemen pengembalian tidak spesifik. * * Lapisan yang mendasarinya benar -benar memanggil kunci hashmap yang mendasarinya untuk mengembalikan semua tombol. * Elemen -elemen dalam hashset dapat dilihat, tetapi disimpan pada kunci hashmap yang mendasarinya, dan nilainya diidentifikasi oleh objek objek akhir statis. * @Return iterator yang berulang kali di atas elemen dalam set ini. */@Override Iterator publik <E> iterator () {return map.keyset (). Iterator ();}/*** Mengembalikan jumlah elemen dalam set ini (kapasitas set). * * Lapisan yang mendasarinya sebenarnya menyebut metode hashmap size () untuk mengembalikan jumlah entri, dan mendapatkan jumlah elemen dalam set. * @Keturn Jumlah elemen dalam set ini (kapasitas set). */@Override public int size () {return map.size ();}/*** Return true jika set ini tidak mengandung elemen apa pun. * * Lapisan yang mendasarinya sebenarnya memanggil ISempty () dari HashMap untuk menentukan apakah hashset kosong. * @Return Return true jika set ini tidak mengandung elemen apa pun. */@Override public boolean isEmpty () {return map.isempty ();}/*** Return true jika set ini berisi elemen yang ditentukan. * Lebih khusus lagi, true dikembalikan jika dan hanya jika set ini berisi elemen E yang memuaskan (o == null? E == NULL: O.Equals (E)) *. * * Berisi dari panggilan aktual yang mendasari ke hashmap menentukan apakah itu berisi kunci yang ditentukan. * @param o keberadaan elemen dalam set ini telah diuji. * @Return Return true jika set ini berisi elemen yang ditentukan. */@Override public boolean berisi (objek o) {return map.containskey (o);}/*** Jika elemen yang ditentukan tidak termasuk dalam set ini, tambahkan elemen yang ditentukan. * Lebih khusus, jika set ini tidak mengandung elemen E2 yang memenuhi (E == NULL? E2 == NULL: E.Equals (E2)) *, elemen E yang ditentukan ditambahkan ke set ini. * Jika set ini sudah berisi elemen, panggilan tidak mengubah set dan mengembalikan false. * * Lapisan yang mendasarinya benar -benar akan menempatkan elemen sebagai kunci ke dalam hashmap. * Karena metode hashmap () menambahkan pasangan nilai kunci, ketika kunci dalam entri baru hashmap * sama dengan kunci entri asli dalam koleksi (hashcode () pengembalian yang sama, dan juga mengembalikan true melalui perbandingan yang sama), * nilai entri yang baru ditambahkan akan menimpa nilai entri asli tidak akan tidak akan diubah. * Oleh karena itu, jika elemen yang ada ditambahkan ke hashset, elemen koleksi yang baru ditambahkan tidak akan dimasukkan ke dalam hashmap, dan * elemen asli tidak akan mengubah apapun, yang memenuhi fitur non-pengulangan elemen dalam set. * @param e elemen yang akan ditambahkan ke set ini. * @Return Return true jika set ini tidak berisi elemen yang ditentukan. */@Override public boolean add (e e) {return map.put (e, present) == null;}/*** Jika elemen yang ditentukan ada dalam set ini, itu akan dihapus. * Lebih khusus, jika set ini berisi elemen E yang memenuhi (o == null? E == null: o.Equals (e)), * akan menghapusnya. Kembalikan true jika set ini sudah berisi elemen (atau: true jika set ini berubah karena panggilan). (Setelah panggilan kembali, set ini tidak lagi berisi elemen). * * Lapisan yang mendasarinya sebenarnya memanggil metode hapus hashmap untuk menghapus entri yang ditentukan. * @param O objek yang perlu dihapus jika ada di set ini. * @return return true jika set berisi elemen yang ditentukan. */@Override public boolean hapus (objek o) {return map.remove (o) == hadir;}/*** Hapus semua elemen dari set ini. Setelah panggilan ini kembali, set akan kosong. * * Lapisan yang mendasarinya sebenarnya menyebut metode hashmap yang jelas untuk menghapus semua elemen dalam masuk. */@Override public void clear () {map.clear ();}}Meringkaskan
Di atas adalah semua isi artikel ini tentang analisis prinsip penghapusan hashset dari nilai duplikat. Saya harap ini akan membantu semua orang. Teman yang tertarik dapat terus merujuk ke topik terkait lainnya di situs ini. Jika ada kekurangan, silakan tinggalkan pesan untuk menunjukkannya. Terima kasih teman atas dukungan Anda untuk situs ini!