java utiliser Utilisez Objects.hash() ou votre propre implémentation hashCode()?




openclassroom java hashcode (3)

Je voudrais essayer de faire un argument solide pour les deux.

Avertissement d'ouverture

Pour cette réponse, Objects.hash() , Objects.hashCode() et toute fonction fournie par une bibliothèque qui effectue ce rôle sont interchangeables. Tout d'abord, je voudrais argumenter, utilisez Objects.hash() ou n'utilisez pas les fonctions d'objets statiques du tout. Tout argument pour ou contre cette méthode nécessite de faire des suppositions sur le code compilé dont la validité n'est pas garantie. (Par exemple, l'optimiseur du compilateur peut convertir l'appel de la fonction en un appel en ligne, évitant ainsi la pile d'appels et l'allocation d'objets supplémentaires, tout comme les boucles qui ne servent à rien ne le font pas (sauf si vous désactivez le optimiseur) Vous ne pouvez pas non plus garantir que les futures versions de Java n'incluront pas la version JVM comme le fait C # dans sa version de cette méthode (pour des raisons de sécurité je crois)) Donc le seul argument que vous pouvez faire pour utiliser cette fonction, C'est qu'il est généralement plus sûr de laisser les détails d'un hachage propre à cette fonction que d'essayer de mettre en œuvre votre propre version naïve.

Pour Objects.hash

  • Garanti pour être un bon hash.
  • Prend 5 secondes pour l'implémenter.
  • Le vôtre aurait eu un bogue dedans (en quelque sorte surtout si vous avez copié-collé l'implémentation)

Contre Objects.hash

  • Les docs Java ne font aucune promesse au sujet de la compatibilité croisée de hachage (une JVM v6 et JVM v8 donneront-elles les mêmes valeurs? Toujours? Sur l'OS?)
  • La chose à propos de hashCodes , ils fonctionnent mieux si "uniformément distribué". Donc, si une valeur int est valide uniquement pour la plage 1 à 100, vous pouvez souhaiter "redistribuer" ses codes de hachage pour ne pas tous faire partie du même compartiment.
  • Si vous avez des questions qui vous amènent à douter du fonctionnement de Objects.hash, de la fiabilité / des performances, réfléchissez bien si le code de hachage correspond vraiment à vos attentes et implémentez une méthode de hachage personnalisée répondant à vos besoins.

J'ai récemment découvert la méthode Objects.hash() .

Ma première pensée a été, que cela range beaucoup votre implémentation hashCode() . Voir l'exemple suivant:

@Override
//traditional
public int hashCode() {
    int hash = 5;
    hash = 67 * hash + (int)(this.id ^ (this.id >>> 32));
    hash = 67 * hash + (int)(this.timestamp ^ (this.timestamp >>> 32));
    hash = 67 * hash + Objects.hashCode(this.severity);
    hash = 67 * hash + Objects.hashCode(this.thread);
    hash = 67 * hash + Objects.hashCode(this.classPath);
    hash = 67 * hash + Objects.hashCode(this.message);
    return hash;
}

@Override
//lazy
public int hashCode() {
    return Objects.hash(id, timestamp, severity, thread, classPath, message);
}

Bien que je dois dire que cela semble trop beau pour être vrai. Aussi, je n'ai jamais vu cet usage.

Y a-t-il des inconvénients à utiliser Objects.hash() par rapport à l'implémentation de votre propre code de hachage? Quand choisirais-je chacune de ces approches?

Mettre à jour

Bien que ce sujet soit marqué comme résolu, n'hésitez pas à publier des réponses qui fournissent de nouvelles informations et préoccupations.


Voici l'implémentation de Objects.hash - qui appelle Arrays.hashCode en interne.

public static int hash(Object... values) {
    return Arrays.hashCode(values);
}

C'est l'implémentation de la méthode Arrays.hashCode

public static int hashCode(Object a[]) {
    if (a == null)
        return 0;

    int result = 1;

    for (Object element : a)
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}

Donc, je suis d'accord avec @Andy Le coût de création de ces objets "inutiles" peut s'accumuler si hashCode est appelé fréquemment. Si vous vous implémentez, ce serait plus rapide.


Notez que le paramètre de Objects.hash est Object... Cela a deux conséquences principales:

  • Les valeurs primitives utilisées dans le calcul du code de hachage doivent être encadrées, par exemple this.id est converti de long en Long .
  • Un Object[] doit être créé pour appeler la méthode.

Le coût de création de ces objets "inutiles" peut s'accumuler si hashCode est appelé fréquemment.





hash