Saya memiliki satu set dengan dua objek berbeda yang ditambahkan ke dalamnya. Setelah penyisipan, saya mengubah salah satu objek sedemikian rupa sehingga kedua objek itu sama (seperti yang diverifikasi oleh metode equals yang diganti di kelas objek). Saat ini saya memiliki dua elemen duplikat dalam satu set. Sekarang saya mencoba menambahkan dua objek duplikat ini dalam set baru dan saya masih dapat menambahkannya meskipun metode equals mengembalikan nilai true untuk mereka. Di bawah ini adalah kode untuk hal yang sama. Dapatkah seseorang tolong beri tahu saya apa sebenarnya yang saya lewatkan?

public class BasicSetImpl{
public int num; String entry;
public BasicSetImpl(int num, String entry){
  this.num = num;
  this.entry = entry;
}

@Override
public int hashCode() {
  return Objects.hash(entry, num);
}

@Override
public boolean equals(Object obj) {
  BasicSetImpl newObj = (BasicSetImpl)obj;
  if (this.num == newObj.num)
    return true;
  else
    return false; 
}



public static void main(String[] args){
  Set<BasicSetImpl> set = new HashSet<>();
  BasicSetImpl k1 = new BasicSetImpl(1, "One");
  BasicSetImpl k2 = new BasicSetImpl(2, "Two");
  set.add(k1);
  set.add(k2);
  
  k2.num = 1;
  
  System.out.println(k1.equals(k2));  //This line returns True
  
  Set<BasicSetImpl> newSet = new HashSet<>();
  newSet.add(k1);
  newSet.add(k2);
  
  //Set.size here is two
-2
shaktiimaannn 12 Mei 2021, 12:14

2 jawaban

Jawaban Terbaik

Koleksi berbasis hash, dalam hal ini HashSet menggunakan metode Object hashCode untuk menghitung nilai hash sebagai fungsi dari isi objek. Karena Anda mempertimbangkan entri dan num untuk menentukan nilai kode hash objek, kedua objek ini memiliki kode hash yang berbeda karena berbeda dari entri. Jadi mereka termasuk dalam dua ember hash yang berbeda dan tidak pernah dikenali sebagai yang sama.

Namun, jika Anda mengatur entri sebagai berikut:

k2.entry = "One";

Maka baik k1 dan k2 memiliki nilai kode hash yang sama. Kemudian keduanya termasuk dalam ember hash yang sama dan menurut metode equals dua objek adalah sama. Oleh karena itu, sekarang duplikat diabaikan.

Tapi, ada masalah yang mengintai di sini. Idealnya, objek yang sama harus memiliki kode hash yang sama. Tapi, dalam kasus Anda tidak. Dua objek adalah sama jika mereka memiliki nilai num yang sama, tetapi mereka dapat menghasilkan nilai kode hash yang berbeda. Jadi solusi yang tepat adalah dengan hanya mengubah kode hash Anda sebagai berikut.

@Override
public int hashCode() {
    return Integer.hashCode(num);
}

Sekarang, itu akan berperilaku seperti yang Anda harapkan tanpa peretasan yang kami tambahkan dengan menyetel k2.entry = "One";

0
Ravindra Ranwala 12 Mei 2021, 09:35

Metode hashCode dan equals harus konsisten.

Dari dokumentasi

Jika dua objek sama menurut metode equals(Object), maka memanggil metode hashCode pada masing-masing dari dua objek harus menghasilkan hasil integer yang sama.

Dalam kasus Anda, meskipun mereka sama, hashCodenya berbeda. Saat menambahkan elemen HashSet periksa hashe dari objek yang ditambahkan dan hanya jika ada objek yang ada di set dengan hash yang sama, HashSet periksa apakah objek ini dengan hash yang sama adalah sama.

0
dim-an 12 Mei 2021, 09:36