Daftar di Java dapat berisi elemen berulang (kode hash dan yang setara), jadi ada dua cara untuk menghapus duplikat Daftar:
Opsi 1: Dapat diimplementasikan melalui HashSet. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
siswa kelas {
id String pribadi;
nama String pribadi;
Siswa publik(ID string, nama string) {
super();
ini.id = id;
ini.nama = nama;
}
@Mengesampingkan
String publik keString() {
return "Siswa [id=" + id + ", nama=" + nama + "]";
}
@Mengesampingkan
kode hash int publik() {
int akhir prima = 31;
int hasil = 1;
hasil = prima * hasil + ((id == null) ? 0 : id.hashCode());
hasil = prima * hasil + ((nama == null) ? 0 : nama.hashCode());
hasil pengembalian;
}
@Mengesampingkan
boolean publik sama dengan(Obj objek) {
jika (ini == keberatan) {
kembali benar;
}
jika (obj == nol) {
kembali salah;
}
jika (getClass() != obj.getClass()) {
kembali salah;
}
Siswa lain = (Siswa) objek;
jika (id == nol) {
if (other.id != null) {
kembali salah;
}
} else if (!id.equals(other.id)) {
kembali salah;
}
jika (nama == batal) {
if (nama lain != null) {
kembali salah;
}
} else if (!nama.sama dengan(nama.lain)) {
kembali salah;
}
kembali benar;
}
}
Dua metode, kode hash dan sama dengan, harus diterapkan. Kita akan segera melihat mengapa kode operasi spesifik harus diterapkan sebagai berikut:
Copy kode kodenya sebagai berikut:
pribadi statis kekosongan hapusListDuplikatObject() {
Daftar<Mahasiswa> daftar = Daftar Array baru<Mahasiswa>();
untuk (int saya = 0; saya < 10; saya++) {
Siswa Siswa = Siswa baru("id", "nama");
list.add(siswa);
}
System.out.println(Arrays.toString(list.toArray()));
Set<Mahasiswa> set = HashSet<Mahasiswa>();
set.addAll(daftar);
System.out.println(Arrays.toString(set.toArray()));
list.removeAll(daftar);
set.removeAll(set);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(set.toArray()));
}
Kode panggilan:
Copy kode kodenya sebagai berikut:
public static void main(String[] args) {
hapusDaftarDuplikatObjek();
}
Saat menggunakan HashSet untuk melakukan operasi deduplikasi, mengapa kita perlu mengganti metode hashCode dan sama dengan?
Mari kita periksa kode sumber operasi penambahan HashSet sebagai berikut:
Copy kode kodenya sebagai berikut:
penambahan boolean publik(E e) {
kembali peta.put(e, PRESENT)==null;
}
HashMap dipanggil untuk operasi. Mari kita lihat operasi put dari HashMap:
Copy kode kodenya sebagai berikut:
publik V put(K kunci, nilai V) {
jika (kunci == nol)
kembalikan putForNullKey(nilai);
int hash = hash(kunci.hashCode());
int i = indexFor(hash, tabel.panjang);
for (Masuk<K,V> e = tabel[i]; e != null; e = e.selanjutnya) {
Objek k;
if (e.hash == hash && ((k = e.key) == kunci || kunci.sama dengan(k))) {
V oldValue = e.value;
e.nilai = nilai;
e.recordAccess(ini);
kembalikan Nilai lama;
}
}
modCount++;
addEntry(hash, kunci, nilai, i);
kembalikan nol;
}
Hal yang perlu diperhatikan adalah:
Copy kode kodenya sebagai berikut:
if (e.hash == hash && ((k = e.key) == kunci || kunci.sama dengan(k))) {
...
}
Dengan kata lain, kode hashnya sama dan sama dengan(==).
Kompleksitas: Cukup melintasi satu sisi, O(n)
Opsi 2: Langsung melintasi Daftar dan menerapkan operasi isi dan penambahan.
Copy kode kodenya sebagai berikut:
privat static void hapusListDuplikatObjectByList() {
Daftar<Mahasiswa> daftar = Daftar Array baru<Mahasiswa>();
untuk (int saya = 0; saya < 10; saya++) {
Siswa Siswa = Siswa baru("id", "nama");
list.add(siswa);
}
System.out.println(Arrays.toString(list.toArray()));
Daftar<Mahasiswa> listUniq = Daftar Array baru<Mahasiswa>();
for (Mahasiswa : daftar) {
if (!listUniq.contains(siswa)) {
listUniq.add(siswa);
}
}
System.out.println(Arrays.toString(listUniq.toArray()));
list.removeAll(daftar);
listUniq.removeAll(listUniq);
System.out.println(Arrays.toString(list.toArray()));
System.out.println(Arrays.toString(listUniq.toArray()));
}
Lainnya sama seperti di atas.
Kompleksitas:
Saat melintasi, metode berisi dipanggil pada saat yang sama. Kami melihat kode sumber sebagai berikut:
Copy kode kodenya sebagai berikut:
boolean publik berisi(Objek o) {
kembalikan indeksDari(o) >= 0;
}
public int indexOf(Objek o) {
jika (o == nol) {
untuk (int i = 0; i < ukuran; i++)
jika (elemenData[i]==null)
kembalikan saya;
} kalau tidak {
untuk (int i = 0; i < ukuran; i++)
if (o.sama dengan(elemenData[i]))
kembalikan saya;
}
kembali -1;
}
Anda dapat melihat bahwa operasi traversal lain telah dilakukan pada daftar baru. Artinya, 1+2+....+n, kompleksitasnya adalah O(n*n)
kesimpulannya:
Solusi 1 sangat efisien, yaitu menggunakan HashSet untuk melakukan operasi deduplikasi.