Test de la chaîne de l'égalité à l'aide de hashCode()
Est-il une raison pourquoi Java string ne peut pas être testé pour l'égalité à l'aide de sa méthode hashCode? Donc, en gros, au lieu de....
"hello".equals("hello")
Vous pouvez utiliser...
"hello".hashCode() == "hello".hashCode()
Ce serait utile car une fois qu'une chaîne est calculé, il est hashcode puis de les comparer une chaîne serait aussi efficace que la comparaison des int comme la chaîne met en cache le hashcode et il est fort probable que la chaîne est la chaîne de la piscine, de toute façon, si vous avez conçu de cette façon.
- Votre réponse se trouve dans la documentation sur le
equals()
ethashcode()
méthodes. - Et concernant l'efficacité énergétique: les regarder de plus près à la les chaînes que vous comparez. Je serai prêt à parier qu' > 50% diffèrent par leur premier caractère, et > 66% diffèrent dans leurs deux premiers caractères. Si vous avez réellement un très efficace en comparaison avec hashCode(), qui doit marcher à l'ensemble de la chaîne. De Plus, si vous utilisez des chaînes dans le constant pool, equals() vérifie d'abord de l'identité, qui donnera un coup de pied ceux tout de suite.
- Il est vrai que le pire scénario est que les chaînes correspondent réellement, ce qui pourrait aussi être le scénario le plus courant. Vous avez également répondu à ma chaîne de performances de la question, tous les gains réalisés par une mise en commun des hashcode est fait déjà de l'exécution d'une instance de contrôle. Cheers!
- Ce que je trouve étrange, c'est que l'actuelle Chaîne de mise en œuvre des caches de la hashCode, mais ne l'utilise pas dans equals(), même si ce serait un moyen rapide d'éliminer l'inégalité des chaînes dans de nombreux cas, un grand gain dans le (certes rares) cas où vous comparez des chaînes avec de longues identiques préfixes.
Vous devez vous connecter pour publier un commentaire.
parce que: hashCodes de deux objets doivent être égales si les objets sont égaux, cependant, si les deux objets sont inégaux, le hashCode peut encore être égaux.
(modifié d'après le commentaire)
Permettez-moi de vous donner un contre-exemple. Essayez ceci,
Le résultat sur mon Java,
comme beaucoup ont dit hashCode ne garantit pas l'unicité.
en fait, il ne peut pas le faire pour une raison très simple.
hashCode retourne un int, ce qui signifie qu'il y a 2^32 valeurs possibles (autour de 4,000,000,000), mais il y a sûrement plus de 2^32 possible des chaînes, ce qui signifie qu'au moins deux phrases ont le même hashcode valeur.
ce qui est appelé Casier principe.
D'autres l'ont fait pourquoi il ne fonctionne pas. Donc je vais juste ajouter de l'additif que le gain serait minime de toute façon.
Quand on compare deux chaînes de caractères en Java, la Chaîne est égale à la fonction vérifie d'abord si ils sont deux références pour le même objet. Si oui, il retourne immédiatement le vrai. Elle vérifie ensuite si les longueurs sont égales. Sinon, elle retourne false. Alors seulement sera-t-elle la comparaison caractère par caractère.
Si vous êtes à la manipulation des données dans la mémoire, le même objet peut comparer rapidement la poignée de la "même" cas, et c'est un moyen rapide, umm, entier de 4 octets comparer, je pense. (Quelqu'un me corrige si j'ai de la longueur d'un objet poignée de mal.)
Pour plus d'inégalités cordes, je serais prêt à parier de la longueur de comparer rapidement les trouve pas égaux. Si vous êtes à la comparaison de deux noms de choses, les clients, les villes, les produits, n'importe quoi, ils ont généralement de longueur inégale. Ainsi, un simple int de comparer rapidement dispose d'entre eux.
Le pire des cas pour la performance va être deux de long, à l'identique, mais pas le même objet cordes. Alors, il doit faire l'objet poignée de comparer, de faux, de garder le contrôle. La longueur de comparer, de vrai, de garder le contrôle. Ensuite, caractère par caractère sur toute la longueur de la chaîne pour vérifier que oui, en effet, ils sont égaux tout le chemin à la fin.
String
classe elle-même.long
qui est incrémenté chaque fois que l'on est créé], unstring
, et une référence à une instance plus ancienne qui est connu pour de match, alors quand deux objets wrappers trouver que distincte de la chaîne d'instances de match, celle qui contient une référence à un "récent" de la chaîne peut être mis à jour pour tenir le plus ancien de la chaîne d'instance qui est connu pour être égaux.Vous pouvez obtenir l'effet que vous souhaitez à l'aide de
String.intern()
(qui est mis en œuvre à l'aide d'une table de hachage.)Vous pouvez comparer les valeurs de retour de
intern()
à l'aide de la==
de l'opérateur. Si elles se réfèrent à la même chaîne les chaînes étaient équivalents (c'est à direequals()
aurait retournétrue
), et elle ne nécessite qu'un pointeur de comparaison (qui a le même coût que unint
comparaison).De sortie:
Le hashCode de la valeur n'est pas unique, ce qui signifie que les Chaînes ne peut pas réellement le match. Pour améliorer les performances, souvent implémentations d'égal à égal effectuera un hashCode vérifier avant d'effectuer plus laborieuse contrôles.
Raison très simple: les risques de collisions...
Un code de hachage auront beaucoup moins de valeurs possibles qu'une chaîne de caractères. Ça dépend un peu du type de hachage vous générer, mais prenons un exemple très simple, lorsque vous ajoutez les valeurs ordinales de lettres, multipliée par sa position: a=1, b=2, etc. Ainsi, "bonjour" serait traduit:
h: 8x1=8, e: 5x2=10, l: 12x3=36, l: 12x4=48, o: 15x5=75. 8+10+36+48+75=177.
Existe-il d'autres valeurs de chaîne qui pourrait mettre fin à 177 haché? Bien sûr! Beaucoup d'options. Hésitez pas à calculer un peu.
Encore, cette méthode de hachage utilisé une méthode simple. Java et .NET use de plus en plus complexe algorithme de hachage avec beaucoup moins de chance de telles collisions. Mais encore, il ya une chance que les deux chaînes entraînera la même valeur de hachage, donc cette méthode est moins fiable.
Deux différents Chaîne peut facilement générer le même Code de hachage ou différents Code de hachage.
Si tu veux un test d'égalité de Code de hachage ne donnera pas un résultat unique. Lorsque nous utilisons la classe String, il sera de retour différente de la valeur de Code de hachage. Donc, tampon de Chaîne de classe doit être appliquer pour avoir le même Code de hachage pour chaque concated objet.
Il n'y a pas de raison de ne pas utiliser hashCode comme vous le décrivez.
Cependant, vous devez être conscient de collisions. Il y a une chance, une petite chance, il est vrai - que les deux chaînes ne hachage à la même valeur. Pensez à faire un hashCode au premier abord, et si l'égalité aussi faire la comparaison complète à l'aide de la equals().