web-dev-qa-db-fra.com

Java: Objets en double ajoutés pour définir?

Si je lance le code ci-dessous, la sortie est 2, ce qui signifie que l'ensemble contient 2 éléments. Cependant, je pense que l'ensemble devrait contenir 1 car les deux objets sont égaux en fonction de la valeur hashcode () ainsi que de la méthode .equals(). Semble comme une erreur évidente dans ma compréhension?

package HELLO;

import Java.util.HashSet;
import Java.util.Set;

public class Test {

    public static void main(String[] args) throws Exception {
        Set<Alpha> s = new HashSet<Alpha>();
        Alpha a1 = new Alpha();
        Alpha a2 = new Alpha();
        s.add(a1);
        s.add(a2);
        System.out.println(s.size());
    }
}   

class Alpha {
    int a = 10;

    public int hashcode() {
        return a;
    }

    public boolean equals(Object obj) {
        return (obj instanceof Alpha && ((Alpha) obj).a == this.a);
    }

    public String toString() {
        return "Alpha : " + a;
    }
}
16
snow_leopard

Votre hachagecla méthode ode ne remplace pas le hachage de la classe ObjectCla méthode ode et donc votre méthode equals rompt le contrat car elle n'est pas d'accord avec les résultats de hashCode, et vous pouvez avoir des objets qui sont "égaux" mais ont des hashCodes différents.

N'oubliez pas: vous devez toujours utiliser le @Override annotation lors de la substitution des méthodes car cela vous aidera à détecter cette erreur et des erreurs similaires.

@Override  // ** don't forget this annotation
public int hashCode() { // *** note capitalization of the "C"
  return a;
}

En outre, vous souhaiterez améliorer la mise en forme de votre code, en particulier lorsque vous publiez du code ici pour notre examen. Nous pourrons mieux comprendre votre code et vous aider s'il est conforme aux normes (c'est pourquoi les normes existent). Essayez donc de garder vos indentations cohérentes avec toutes les lignes de code qui se trouvent dans le même bloc en retrait au même niveau, et vous voudrez vous assurer que le code de niveau de base, y compris les importations, les déclarations de classe externe et son accolade finale, est aligné à gauche :

import Java.util.HashSet;
import Java.util.Set;

public class Test {

   public static void main(String[] args) throws Exception {
      Set<Alpha> s = new HashSet<Alpha>();
      Alpha a1 = new Alpha();
      Alpha a2 = new Alpha();
      s.add(a1);
      s.add(a2);
      System.out.println(s.size());
   }
}

class Alpha {
   int a = 10;

   @Override
   public int hashCode() {
      return a;
   }

   public String toString() {
      return "Alpha : " + a;
   }

   @Override
   public boolean equals(Object obj) {
      if (this == obj)
         return true;
      if (obj == null)
         return false;
      if (getClass() != obj.getClass())
         return false;
      Alpha other = (Alpha) obj;
      if (a != other.a)
         return false;
      return true;
   }
}

Pour une belle critique à ce sujet, veuillez lire: Remplacer les égaux et hashCode en Java

votre méthode hashcode doit être nommée hashCode (lettre majuscule "C").

Si vous prévoyez de remplacer les méthodes, vous devez utiliser le @Override annotation.

Si vous aviez utilisé cette annotation, vous auriez remarqué le problème plus tôt car le code n'aurait pas été compilé.

4
Mena

L'annotation @Overrides consiste à remplacer la méthode du même nom dans la super classe ".

@Override
public int hashCode() {
    return a;
}

@Override
public boolean equals(Object obj) {
    return (obj instanceof Alpha && ((Alpha) obj).a == this.a);

}

@Override
public String toString() {
    return "Alpha : " + a;
}
3
Suresh Atta