[Lire Java effectif] Chapitre 3 Rubrique 9 "Lors de la substitution d'égaux, toujours remplacer hashCode"

Remplacez toujours hashCode lorsque vous remplacez égal à

Toutes les classes qui remplacent equals rompent le contrat général pour Object.hashCode à moins qu'elles ne remplacent également hashCode.

Exemple de code

Le code ci-dessous remplace égal hashCode ne remplace pas

Exemple 1


public final class PhoneNumber {
    private final short areaCode;
    private final short prefix;
    private final short lineNumber;

    public PhoneNumber(int areaCode, int prefix,
                       int lineNumber){
        rangeCheck(areaCode, 999, "area code");
        rangeCheck(prefix, 999, "prefix");
        rangeCheck(lineNumber, 9999, "line number");
        this.areaCode = (short)areaCode;
        this.prefix = (short)prefix;
        this.lineNumber = (short)lineNumber;
    }

    private static void rangeCheck(int arg, int max, 
                                   String name){
        if (arg < 0 || arg > max)
            throw new IllegalArgumentException(name +": " + arg);
    }

    @Override public boolean equals(Object o){
        if (o == this)
            return true;
        if (!(o instanceof PhoneNumber))
            return false;
        PhoneNumber pn = (PhoneNumber)o;
        return pn.lineNumber == lineNumber
            && pn.prefix == prefix
            && pn.areaCode == areaCode;
    }

    //incomplet-Il n'y a pas de méthode hashCode!
    
    ... //Le reste est omis
}

Supposons que l'exemple 1 soit utilisé dans HashMap. Dans l'exemple 2, m.get (new PhoneNumber (707, 867, 5309)) devrait renvoyer " Jenny ", mais il renvoie null. Comme nous n'avons pas remplacé hashCode, le put PhoneNumber et le get PhoneNumber ont des valeurs de hachage différentes.

Exemple 2


Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
m.put(new PhoneNumber(707, 867, 5309), "Jenny");

Ce qui suit n'est qu'un exemple, mais remplaçons hashCode.

Exemple 3



@Override public int hashCode(){
    int result = hashCode;
    if (result == 0){
        result = 17;
        result = 31 * result + areaCode;
        result = 31 * result + prefix;
        result = 31 * result + lineNumber;
        hashCode = result;
    }
    return result;
}

Continuer

[Lire Java efficace] Chapitre 3 Item 10 "Always Override toString" https://qiita.com/Natsukii/items/6e2cd2e77e144048819d

Recommended Posts

[Lire Java effectif] Chapitre 3 Rubrique 9 "Lors de la substitution d'égaux, toujours remplacer hashCode"
[Lire Java efficace] Chapitre 3 Item 10 "Always Override toString"
[Lire Java efficace] Chapitre 3 Point 8 "En cas de remplacement égal, suivez le contrat général"
[Lire Java efficace] Chapitre 2 Item 7 "Eviter les finaliseurs"
[Lire Java efficace] Chapitre 3 Point 12 "Considérer l'implémentation de Comparable"
[Lire Java efficace] Chapitre 2 Item 6 "Supprimer les références d'objets obsolètes"
[Lire Java efficace] Chapitre 2 Item 4 "Forcer l'impossibilité d'immobilisation avec un constructeur privé"
[Lire Java efficace] Chapitre 2 Item 5 "Eviter la création d'objets inutiles"
[Lire le Java efficace] Chapitre 2 Item 2 "Considérez un constructeur face à un grand nombre de paramètres de constructeur"
[Lire Java efficace] Chapitre 2 Item 1 "Considérez les méthodes de fabrique statiques plutôt que les constructeurs"
Efficace Java Chapitre 2
Effective Java Chapitre 6 34-35
Effective Java Chapitre 4 15-22
Java efficace Chapitre 3
[Lire Java efficace] Chapitre 2 Item 3 "Forcer les caractéristiques de singleton avec un constructeur privé ou un type enum"
[Java] HashCode et remplacement égal
Efficacité de Java 3rd Edition Chapitre 5 Génériques
Méthodes efficaces du chapitre 8 de Java 3rd Edition
Comprendre equals et hashCode en Java