Il s'agit d'une question très classique à Java et est souvent posée lors des entretiens. En fait, de nombreux livres ou articles ont mentionné que vous devez surcharger HashCode () et Equals () pour réaliser la recherche de clés personnalisées dans HashMap. Cependant, il semble que peu d'articles expliquent pourquoi vous devez faire cela et quelles conséquences seront causées par le fait de ne pas le faire, donc j'écrirai cet article pour l'expliquer.
Tout d'abord, que se passe-t-il si nous utilisons directement la classe de personne suivante comme clé et la stockons dans HashMap?
Personne de classe publique {ID de chaîne privée; Public (String id) {this.id = id; }} import java.util.hashmap; public class main {public static void main (string [] args) {hashmap <personne, string> map = new hashmap <personne, string> (); map.put (nouvelle personne ("001"), "FindingSea"); map.put (nouvelle personne ("002"), "Linyin"); map.put (nouvelle personne ("003"), "Henrylin"); map.put (nouvelle personne ("003"), "FindingsAly"); System.out.println (map.toString ()); System.out.println (map.get (nouvelle personne ("001"))); System.out.println (map.get (nouvelle personne ("002"))); System.out.println (map.get (nouvelle personne ("003"))); }}Alors, quel est le résultat de sortie?
{Personne @ 6e4d4d5e = Henrylin, personne @ 275cea3 = FindingSea, personne @ 15128EE5 = FindingSealy, personne @ 4513098 = linyin} nullnullnullNous pouvons voir qu'il y a deux problèmes ici:
1. Pendant le processus d'addition, nous avons ajouté deux fois la paire de valeurs de clé de clé = new ("003"). Dans l'attente, il ne devrait y avoir qu'une seule paire de valeurs clés dans HashMap. Parce que la clé (attendue) est la même, elle ne doit pas être ajoutée à plusieurs reprises. La valeur = "FindingsAly" ajouta la deuxième fois que la deuxième fois devrait remplacer la valeur d'origine = "Henrylin". Mais dans l'entrée, nous avons constaté que la situation attendue ne se produisait pas, mais il y a deux paires de valeurs clés de valeur = "FindingSealy" et Value = "Henrylin" dans Hashmap, et leurs valeurs clés sont toujours différentes, ce qui est évidemment faux.
2. Lors de l'obtention de la valeur de valeur, nous utilisons trois objets de personne pour rechercher. Ces trois objets sont les mêmes que les trois valeurs clés que nous venons de stocker (dans l'attente), mais la recherche est de trois valeurs nulles, ce qui est évidemment également faux.
Ainsi, la bonne méthode a été décrite dans de nombreux endroits. La classe de personne est directement modifiée, surchargée égaux et méthodes de code hashcode, et la classe de personne modifiée est la suivante:
Personne de classe publique {ID de chaîne privée; Public (String id) {this.id = id; } @Override public booléen equals (objet o) {if (this == o) return true; if (o == null || getClass ()! = o.getClass ()) return false; Personne personne = (personne) o; if (id! = null?! id.equals (personne.id): personne.id! = null) return false; Retour Vrai; } @Override public int hashcode () {return id! = Null? id.hashcode (): 0; }}Ensuite, lorsque nous réexécutions la procédure d'inspection ci-dessus, les résultats sont les suivants:
{Personne @ ba31 = FindingSea, personne @ ba32 = linyin, personne @ ba33 = FindingSealy} FindingSelinyInFindingSealyComme on peut le voir, tous les points forts et erreurs soulignés ont été corrigés. Alors, pourquoi cela se produit-il?
Dans Hashmap, l'ordre de comparaison des clés de recherche est:
1. Calculez le code de hachage de l'objet pour voir s'il existe dans le tableau.
2. Vérifiez si l'objet dans l'emplacement du code de hachage correspondant est égal à l'objet actuel.
De toute évidence, la première étape consiste à utiliser la méthode HashCode (), et la deuxième étape consiste à utiliser la méthode equals (). Lorsqu'aucune surcharge n'est effectuée, ces deux méthodes de la classe d'objets seront appelées par défaut dans ces deux étapes. Dans l'objet, la méthode de calcul du code de hachage est calculée en fonction de l'adresse de l'objet. Les adresses d'objet des deux personnes ("003") sont différentes, donc leur code de hachage est également différent. Naturellement, Hashmap ne les traitera pas comme la même clé. Dans le même temps, dans les égaux par défaut () de l'objet, il est également comparé sur la base de l'adresse de l'objet. Naturellement, une personne ("003") et une autre personne ("003") ne sont pas égales.
Après avoir compris cela, il est facile de comprendre pourquoi vous devez surcharger à la fois HashCode () et égal aux méthodes.
• La surcharge de HashCode () est d'obtenir le même code de hachage pour la même clé, afin que le hashmap puisse être positionné sur la clé que nous avons spécifiée.
• La surcharge équivalent () consiste à afficher HashMap que l'objet actuel et l'objet enregistrés sur la clé sont égaux, afin que nous puissions vraiment obtenir la paire de valeurs de clé correspondant à la clé.
Il y a un autre détail. Dans la classe de personne, l'accent mis sur HashCode () est:
@OverridePublic int hashcode () {return id! = Null? id.hashcode (): 0;}Le point qui peut être perplexe ici est: pourquoi le code de hachage d'une variable de chaîne de type peut-il être utilisé comme valeur de code de hachage de la classe de personne? Les codes de hachage de la nouvelle personne (nouvelle chaîne ("003")) sont-ils égaux sont égaux sont égaux?
Jetons un coup d'œil à la sortie du code suivant:
System.out.println ("FindingSea" .HashCode ()); System.out.println ("FindingSa" .HashCode ()); System.out.println (new String ("FindingSea"). HashCode ()); System.out.println (new String ("FindingSa"). HashCode ()); 728795174728795174728795174728795174Vous pouvez voir que les sorties des quatre instructions sont toutes égales. Il est très intuitif et raisonnable de deviner que le type de chaîne surcharge également HashCode () pour renvoyer la valeur de code de hachage en fonction du contenu de la chaîne, donc les chaînes avec le même contenu ont le même code de hachage.
Dans le même temps, cela illustre également une question: pourquoi devons-nous utiliser equals () à titre de comparaison lorsque nous savons que HashCode () est égal? C'est parce qu'il évite la situation dans l'exemple ci-dessus, car en fonction de l'implémentation de surcharge de la méthode HashCode () de la classe de personne, la classe de personne utilisera directement la valeur de code de hash de l'ID de membre du type de chaîne comme valeur de code de hash. Cependant, il est évident qu'une personne ("003") et une chaîne ("003") ne sont pas égales, donc lorsque hashcode () est égal, equals () est également nécessaire pour comparer.
Les exemples suivants peuvent être utilisés comme preuve de la description ci-dessus:
System.out.println (nouvelle personne ("003"). HashCode ()); // 47667System.out.println (new String ("003"). HashCode ()); // 47667System.out.println (nouvelle personne ("003"). Equaux (new String ("003"))); // FAUXL'article ci-dessus Java utilise des classes personnalisées comme exemple de valeur clé de hashmap. C'est tout le contenu que je partage avec vous. J'espère que cela pourra vous donner une référence et j'espère que vous pourrez soutenir Wulin.com plus.