CodeGym /Blog Java /Random-FR /Code de hachage Java ()
Auteur
Oleksandr Miadelets
Head of Developers Team at CodeGym

Code de hachage Java ()

Publié dans le groupe Random-FR

Principe de hachage

Tout d'abord, avant de définir le hashcode Java, nous devons comprendre ce qu'est le hachage et à quoi il sert. Le hachage est un processus d'application d'une fonction de hachage à certaines données. Une fonction de hachage n'est qu'une fonction mathématique. Ne vous inquiétez pas pour ça ! « Mathématique » ne veut pas toujours dire « compliqué ». Ici, cela signifie seulement que nous avons des données et une certaine règle qui mappe les données dans un ensemble de caractères (code). Par exemple, il pourrait s'agir d'un chiffrement hexadécimal. Nous avons des données de n'importe quelle taille à l'entrée et nous leur appliquons une fonction de hachage. En sortie, nous obtenons des données de taille fixe, disons 32 caractères. Habituellement, ce type de fonction convertit un gros morceau de données en une petite valeur entière. Le résultat de ce travail de fonction est appelé un code de hachage. Les fonctions de hachage sont largement utilisées en cryptographie, ainsi que dans d'autres domaines. Les fonctions de hachage peuvent être différentes,
  • Un objet particulier a un hashcode particulier.
  • Si deux objets sont égaux, leurs hashcodes sont les mêmes. L'inverse n'est pas vrai.
  • Si les codes de hachage sont différents, alors les objets ne sont pas égaux à coup sûr.
  • Différents objets peuvent avoir le même code de hachage. Cependant, c'est un événement très improbable. À ce stade, nous avons une collision, une situation où nous pouvons perdre des données.
La fonction de hachage "appropriée" minimise la probabilité de collisions.

Code de hachage en Java

En Java, la fonction de hachage est généralement connectée à la méthode hashCode() . Précisément, le résultat de l'application d'une fonction de hachage à un objet est un hashcode. Chaque objet Java a un code de hachage. En général, Hash Code est un nombre calculé par la méthode hashCode() de la Objectclasse. Habituellement, les programmeurs remplacent cette méthode pour leurs objets ainsi que pour hashCode() la méthode equals() pour un traitement plus efficace de données spécifiques. La méthode hashCode() renvoie une valeur int (4 octets), qui est une représentation numérique de l'objet. Ce hashcode est utilisé, par exemple, par les collections pour un stockage plus efficace des données et, par conséquent, un accès plus rapide à celles-ci. Par défaut, le hashCode()fonction pour un objet renvoie le numéro de la cellule mémoire où l'objet est stocké. Par conséquent, si aucune modification n'est apportée au code de l'application, la fonction doit renvoyer la même valeur. Si le code change légèrement, la valeur du hashcode change également. À quoi sert le hashcode en Java ? Tout d'abord, les hashcodes Java aident les programmes à s'exécuter plus rapidement. Par exemple, si nous comparons deux objets o1et o2d'un certain type, l'opération o1.equals(o2)prend environ 20 fois plus de temps que o1.hashCode() == o2.hashCode().

Java est égal à ()

Dans la classe parent Object, avec la méthode hashCode() , il y a aussi equals() , la fonction qui est utilisée pour vérifier l'égalité de deux objets. L'implémentation par défaut de cette fonction vérifie simplement les liens de deux objets pour leur équivalence. equals() et hashCode() ont leur contrat, donc si vous remplacez l'un d'eux, vous devez remplacer l'autre, afin de ne pas rompre ce contrat.

Implémentation de la méthode hashCode()

Exemple

Créons une classe Character avec un champ — name . Après cela, nous créons deux objets de la classe Character , character1 et character2 et leur donnons le même nom. Si nous utilisons les hashCode() et equals() par défaut de la classe Object , nous obtiendrons certainement des objets différents et non égaux. C'est ainsi que fonctionne le hashcode en Java. Ils auront des hashcodes différents car ils se trouvent dans des cellules de mémoire différentes et le résultat de l'opération equals() sera faux.

import java.util.Objects;

public class Character {
    private String Name;

    public Character(String name) {
        Name = name;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    } 

    public static void main(String[] args) {
        Character character1 = new Character("Arnold");
        System.out.println(character1.getName());
        System.out.println(character1.hashCode());
        Character character2 = new Character("Arnold");
        System.out.println(character2.getName());
        System.out.println(character2.hashCode());
        System.out.println(character2.equals(character1));
    }
}
Le résultat de l'exécution du programme:

Arnold
1595428806
Arnold
1072408673
false
Deux nombres à 10 chiffres dans la console sont des hashcodes. Que se passe-t-il si nous voulons avoir des objets égaux s'ils ont les mêmes noms ? Que devrions nous faire? La réponse : nous devrions remplacer les méthodes hashCode() et equals() de la classe Object pour notre classe Character . Nous pourrions le faire automatiquement dans IDEA IDE, appuyez simplement sur alt + insert sur votre clavier et choisissez Generate -> equals() and hashCode() . Qu'est-ce que Java hashCode() - 2Dans le cas de notre exemple, nous avons le code suivant :

import java.util.Objects;

public class Character {
    private String Name;

    public Character(String name) {
        Name = name;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Character)) return false;

        Character character = (Character) o;

        return getName() != null ? getName().equals(character.getName()) : character.getName() == null;
    }

    @Override
    public int hashCode() {
        return getName() != null ? getName().hashCode() : 0;
    }

    public static void main(String[] args) {
        Character character1 = new Character("Arnold");
        System.out.println(character1.getName());
        System.out.println(character1.hashCode());
        Character character2 = new Character("Arnold");
        System.out.println(character2.getName());
        System.out.println(character2.hashCode());
        System.out.println(character2.equals(character1));
    }
}
Le résultat de l'exécution de ce code:

Arnold
1969563338
Arnold
1969563338
true
Alors maintenant, le programme identifie nos objets comme égaux et ils ont les mêmes hashcodes.

Exemple de hashcode Java:

Votre propre hashCode() et equals()

Vous pouvez également créer vos propres réalisations equals() et hashCode() , mais soyez prudent et n'oubliez pas de minimiser les collisions de hashcode. Voici un exemple de nos propres méthodes hashCode() et equals() dans la classe Student :

import java.util.Date;

public class Student {
   String surname;
   String name;
   String secondName;
   Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases

   public Student(String surname, String name, String secondName, Date birthday ){
       this.surname = surname;
       this.name = name;
       this.secondName = secondName;
       this.birthday = birthday == null ? 0 : birthday.getTime();
   }
//Java hashcode example
   @Override
   public int hashCode(){
       //TODO: check for nulls
       //return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());
       return (surname + name + secondName + birthday).hashCode();
   }
   @Override
   public boolean equals(Object other_) {
       Student other = (Student)other_;
       return (surname == null || surname.equals(other.surname) )
               && (name == null || name.equals(other.name))
               && (secondName == null || secondName.equals(other.secondName))
               && (birthday == null || birthday.equals(other.birthday));
   }
}
Et la classe principale pour démontrer leur travail:

import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;

public class Main {
   static HashMap<Student, Integer> cache = new HashMap<Student, Integer>(); // <person, targetPriority>

   public static void main(String[] args) {
       Student sarah1 = new Student("Sarah","Connor", "Jane", null);
       Student sarah2 = new Student("Sarah","Connor", "Jane", new Date(1970, 01-1, 01));
       Student sarah3 = new Student("Sarah","Connor", "Jane", new Date(1959, 02-1, 28)); // date not exists
       Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       Student johnny = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
       System.out.println(john.hashCode());
       System.out.println(johnny.hashCode());
       System.out.println(sarah1.hashCode());
       System.out.println();
       cache.put(sarah1, 1);
       cache.put(sarah2, 2);
       cache.put(sarah3, 3);
       System.out.println(new Date(sarah1.birthday));
       System.out.println();
       cache.put(john, 5);
       System.out.println(cache.get(john));
       System.out.println(cache.get(johnny));
       cache.put(johnny, 7);
       System.out.println(cache.get(john));
       System.out.println(cache.get(johnny));
   }
}

A quoi sert le hashcode?

Tout d'abord, les hashcodes aident les programmes à fonctionner plus rapidement. Par exemple, si nous comparons deux objets o1et o2d'un certain type, l'opération o1.equals(o2)prend environ 20 fois plus de temps que o1.hashCode() == o2.hashCode(). En Java, le principe de hachage est derrière certaines collections populaires, telles que HashMap , HashSet et HashTable.

Conclusion

Chaque objet Java possède les méthodes hashCode() et equals() héritées de la classe Object . Pour obtenir un bon mécanisme d'égalité de travail, vous feriez mieux de remplacer les méthodes hashcode() et equals() pour vos propres classes. L'utilisation de hashcodes accélère l'exécution des programmes.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION