Maison  >  Questions et réponses  >  le corps du texte

初涉继承,关于java中重写hashcode()方法的问题

大家讲道理大家讲道理2763 Il y a quelques jours920

répondre à tous(2)je répondrai

  • PHP中文网

    PHP中文网2017-04-18 10:47:27

    Convention générale d'implémentation des hashCode méthodes

    1. Lors de l'exécution de l'application, tant que les informations utilisées dans l'opération de comparaison de la méthode equals de l'objet ne sont pas modifiées, alors le même objet est appelé plusieurs fois, et la méthode hashCode doit renvoie systématiquement le même nombre entier. Lors de plusieurs exécutions d'une même application, les entiers renvoyés par chaque exécution peuvent être incohérents.

    2. Si deux objets sont égaux selon la comparaison de la méthode equals(Object), alors l'appel de la méthode hashCode de l'un ou l'autre objet doit produire le même résultat entier . Au contraire, si la méthode hashCode de deux objets renvoie le même résultat entier, cela ne signifie pas que les deux objets sont égaux, car la méthode equals peut être surchargée.

    3. Si deux objets ne sont pas égaux selon la comparaison de la méthode equals(Object), alors appeler la méthode hashCode de l'un ou l'autre objet ne produit pas nécessairement des résultats entiers différents. Cependant, si vous pouvez faire en sorte que différents objets produisent des résultats entiers différents, il est possible d'améliorer les performances de la table de hachage.

    hashCodeCalcul du code de hachage (à partir de : Effective Java)

    1. enregistre une valeur constante non nulle, telle que 17, dans une variable de type result nommée int.

    2. Pour chaque champ clé f de l'objet ( fait référence à chaque champ equals impliqué dans la méthode), complétez les étapes suivantes :

      1. Calcule un hash code c de type int pour ce champ :

        1. Évalue (boolean) si le champ est de type f?1:0.

        2. Si le champ est de type byte, char, short ou int, alors (int)f est calculé.

        3. Évalue long si le champ est de type (int)(f^(f>>>32)).

        4. Évalue float si le champ est de type Float.floatToIntBits(f).

        5. Si le champ est de type double, calculez Double.doubleToLongBits(f), puis suivez l'étape 2.1.3 pour calculer une valeur de hachage pour la valeur de type long résultante.

        6. Si le champ est une référence d'objet et que la méthode equals de la classe compare le champ en appelant récursivement equals, alors elle appelle également hashCode de manière récursive pour le champ. Si une comparaison plus complexe est requise, calculez une forme normale (canonical representation) pour le champ, puis appelez hashCode par rapport à cette forme normale. Si la valeur de ce champ est null, alors 0 est renvoyé (d'autres constantes sont également acceptables).

        7. Si le champ est un tableau, chaque élément doit être traité comme un champ distinct. Autrement dit, appliquez les règles ci-dessus de manière récursive, calculez un code de hachage pour chaque élément significatif, puis combinez ces valeurs de hachage selon l'étape 2.2. Si chaque élément du champ du tableau est important, vous pouvez profiter de l'une des méthodes ajoutées dans la version 1.5Arrays.hashCode.

      2. D'après la formule suivante, fusionnez le code de hachage c calculé à l'étape 2.1 dans result : result = 31 * result + c ; //Ici 31 est un nombre premier impair, et il y a un très A. une fonctionnalité intéressante, utilisant des décalages et des soustractions au lieu de multiplications, peut conduire à de meilleures performances : `31*i == (i<<5) - i.

    3. Retourresult

    4. Vérifiez et testez que l'implémentation hashCode est conforme aux conventions communes.


    Exemple de mise en œuvre

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + (origin == null ? 0 : origin.hashCode());
        result = 31 * result + (hsNumber == null ? 0 : hsNumber.hashCode());
        result = 31 * result + (imageUrl == null ? 0 : imageUrl.hashCode());
        result = 31 * result + (classificationName == null ? 0 : classificationName.hashCode());
        return result;
    }

    répondre
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:47:27

    L'int de Java est fixé à 32 bits. De plus, votre latitude et votre longitude sont le double... Je pense que ce sera 64 bits.

    Hashcode et ses équivalents ont une sémantique convenue. Vous pouvez jeter un œil à Object

    .

    Je pense que les égaux que vous avez écrits peuvent être utilisés.


    Remarque : Le contrat dans la classe Object est en fait une contrainte très faible. Nous pouvons écrire hashcode() et equals() comme ceci sans violer le contrat ;

    public int hashcode() {
        return 0;
    }
    
    public boolean equals(Object o) {
        return (o != null) && (o.getClass() == getClass());
    }

    La vraie question est donc comment définissez-vous l’égalité. Le code est secondaire.
    Si l'égalité est définie comme "la longitude et la latitude sont respectivement égales", alors le code que vous avez donné est une solution utilisable (mais pas la seule solution disponible).

    répondre
    0
  • Annulerrépondre