7 votes

Implémentation des codes de hachage et des égalités pour les classes personnalisées

J'ai donc de nombreuses classes personnalisées qui ont également des classes personnalisées à l'intérieur d'elles en utilisant la composition.

Mes classes personnalisées ont des variables qui changent très fréquemment et je les ajoute aux HashSets. Ma question est donc la suivante : lorsque j'implémente hashCode - que dois-je faire pour une classe qui n'a que des champs privés qui changent constamment ?

Voici un exemple d'une classe personnalisée :

public class Cell {
    protected boolean isActive;
    protected boolean wasActive;

    public Cell() {
    this.isActive = false;
    this.wasActive = false;
    }

    // getter and setter methods...

    @Override
    public int hashCode() {
    // HOW SHOULD I IMPLEMENT THIS IF THIS custom object is constantly
        // being added into HashSets and have it's private fields isActive
        // and wasActive constantly changed.
    }

    // ANOTHER QUESTION Am I missing anything with this below equals implementation?
    @Override
    public boolean equals(Object object) {
    boolean result = false;
    if (object instanceof Cell) {
        Cell otherCell = (Cell) object;
        result = (this.isActive == otherCell.isActive && this.wasActive == 
            otherCell.wasActive);
    }
    return result;
    }

6voto

Ankur Lathi Points 6280

Contrat Equals et hashCode en Java :

Nous devons surcharger la méthode hashCode() lorsque nous surchargeons la méthode equals(), la méthode equals en Java doit suivre son contrat avec la méthode hashCode en Java comme indiqué ci-dessous.

  1. Si deux objets sont égaux par la méthode equals(), leur code de hachage doit être le même. être le même.
  2. Si deux objets ne sont pas égaux par la méthode equals(), alors leur hashcode peuvent être identiques ou différents.

Voici des exemples d'implémentation des méthodes equals et hashcode pour votre classe :

 //Hashcode Implementation    

   @Override
    public int hashCode() 
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + (isActive ? 1231 : 1237);
        result = prime * result + (wasActive ? 1231 : 1237);
        return result;
    }

//equals Implementation    
    @Override
    public boolean equals(Object obj) 
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Cell other = (Cell) obj;
        if (isActive != other.isActive)
            return false;
        if (wasActive != other.wasActive)
            return false;
        return true;
    }

1voto

Veera Points 1725

Voici l'exemple d'une classe qui a des champs privés.

public class Test {

    private int num;
    private String data;

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        // object must be Test at this point
        Test test = (Test) obj;
        return num == test.num
                && (data == test.data || (data != null && data
                        .equals(test.data)));
    }

    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + num;
        hash = 31 * hash + (null == data ? 0 : data.hashCode());
        return hash;
    }

}

1voto

user949300 Points 7954

Vous êtes SOL. Lorsque hashCode() est utilisé comme clé dans les collections Java standard, il ne devrait pas changer. Sinon, vous avez besoin d'une implémentation personnalisée de type HashSet.

N'utilisez que des champs qui ne changent pas (ou, si vous êtes audacieux et ne craignez pas les plantages occasionnels, des champs qui changent très rarement) pour calculer hashCode().

(Ajouté). Dans votre exemple particulier, utilisez Object.hashCode().

(Ajouté #2) Même si votre classe Cell était immuable (les deux booléens ne changent pas), elle est un mauvais choix pour le hachage, car elle n'a que 2 bits de portée. Imaginez que toutes les personnes soient hachées en fonction de leur sexe et de leurs yeux bleus ou bruns. C'est un très bon début, mais il n'y a que 4 catégories, et il y aura environ 2 milliards de personnes dans chacune d'elles. L'idéal serait d'avoir plusieurs autres catégories, comme l'année de naissance, le pays de naissance, etc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X