Hashcode et Equals for Hashset

S’il vous plaît clarifier mon doute dans Hashset. Considérez le code suivant,

class Person { Ssortingng name; Person(Ssortingng n) { name=n; } public Ssortingng getName() { return name; } @Override public boolean equals(Object arg0) { System.out.println("in equals"); Person obj=(Person)arg0; System.out.println("1st "+getName()); System.out.println("2nd "+obj.getName()); if(this.getName().equals(obj.getName())) { return true; } return false; } @Override public int hashCode() { System.out.println("in hash code"); System.out.println(" value is "+Integer.valueOf(name.charAt(0))); return Integer.valueOf(name.charAt(0)); } } 

dans le principal j’ai le code suivant

 Person obj1=new Person("bcd"); Person obj2=new Person("cde"); Person obj3=new Person("abc"); Person obj4=new Person("abc"); 

Maintenant, si j’ajoute ces objects à hashset

 Set sset=new HashSet(); sset.add(obj1); sset.add(obj4); sset.add(obj2); sset.add(obj3); 

Je reçois cette sortie

 in hash code value is 98 in hash code value is 97 in hash code value is 99 in hash code value is 97 in equals 1st abc 2nd abc 

Question 1 : pourquoi la fonction equals () est appelée une seule fois pour vérifier obj3 et obj4? Pourquoi ce n’est pas vérifié pour le rest des objects?

Question 2 : Si la réponse est que les deux ont le même code de hachage, alors seulement les égaux seront appelés, alors pourquoi n’est-il pas appelé pour le code ci-dessous?

 sset.add(obj1); sset.add(obj4); sset.add(obj2); sset.add(obj4); 

la sortie est:

 in hash code value is 98 in hash code value is 97 in hash code value is 99 in hash code value is 97 

Cela ne va pas dans la méthode equals () même si deux objects identiques sont ajoutés au jeu de hachage qui a le même code de hachage.

Question 3 : J’ai itéré la valeur ci-dessus et imprimé le contenu, mais ni le hashcode ni les égaux n’ont été appelés. Quand c’est vraiment utile pour remplacer le hashcode et la méthode égale?

Question 4 : Quand hashCode() et equals() seront-ils appelés?

  1. Il n’y a pas besoin d’appeler des equals si hashCode diffère.
  2. Il n’y a pas besoin d’appeler hashCode if (obj1 == obj2) .
  3. Il n’y a pas besoin de hashCode et / ou d’ equals à equals pour itérer – vous ne comparez pas d’objects
  4. Si nécessaire pour distinguer entre les objects.

Je pense que vous pourrez répondre à toutes vos questions si vous comprenez comment fonctionnent les Sets, et en particulier les HashSets. Un ensemble est une collection d’objects uniques, avec Java définissant l’unicité en ce sens qu’il ne correspond à rien d’autre (égal à false).

Le HashSet tire parti des codes de hachage pour accélérer les choses. Il suppose que deux objects égaux auront le même code de hachage. Cependant, il ne suppose pas que deux objects ayant le même code de hachage signifient qu’ils sont égaux. C’est pourquoi, lorsqu’il détecte un code de hachage en collision, il se compare uniquement aux autres objects (dans votre cas) dans le même ensemble avec le même code de hachage.

Selon le code source jdk de javasourcecode.org, HashSet utilise HashMap comme implémentation interne, le code de la méthode put de HashSet est ci-dessous:

 public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } 

La règle est tout d’abord de vérifier le hachage, puis de vérifier la référence puis d’appeler la méthode de l’object qui sera introduite.

Parce que dans le deuxième cas, vous ajoutez la même référence deux fois et HashSet a vérifié dans HashMap.put() sur lequel HashSet est basé:

  if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } 

Comme vous pouvez le voir, les equals seront appelés uniquement si le hachage de la clé ajouté est égal à la clé déjà présente dans l’ensemble et les références de ces deux sont différentes.

Vous devriez vous renseigner sur la façon de vous assurer que vous avez correctement mis en œuvre et hashCode. C’est un bon sharepoint départ: Quels problèmes doivent être pris en compte lors de la substitution d’égaux et de hashCode en Java?

S’il vous plaît déboguer HashSet avec toutes ses méthodes et vous verrez comment cela fonctionne