Question

Y at-il des raisons pour lesquelles une chaîne Java ne peut pas être testé pour l'égalité en utilisant c'est la 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 une chaîne a calculé qu'il est hashcode alors comparer une chaîne serait aussi efficace que la comparaison d'un int comme la chaîne met en cache la hashcode et il est fort probable que la chaîne est dans la piscine de chaîne de toute façon, si vous conçu de cette façon.

Était-ce utile?

La solution

parce que:. Hashcodes de deux objets doivent être égaux si les objets sont égaux, cependant, si deux objets sont inégaux, le hashCode peuvent encore être égaux

(modifié après un commentaire)

Autres conseils

Permettez-moi de vous donner un contre-exemple. Essayez ceci,

public static void main(String[] args) {
    String str1 = "0-42L";
    String str2 = "0-43-";

    System.out.println("String equality: " + str1.equals(str2));
    System.out.println("HashCode eqauality: " + (str1.hashCode() == str2.hashCode()));
}

Le résultat sur mon Java,

String equality: false
HashCode eqauality: true

comme beaucoup ont dit hashCode ne pas l'unicité de garantie. en fait, il ne peut pas le faire pour une raison très simple.

hashCode renvoie un int, ce qui signifie qu'il y a 2 ^ 32 valeurs possibles (environ 4000000000), mais il y a certainement plus de 2 ^ 32 chaînes possibles, ce qui signifie au moins deux chaînes ont la même valeur de code de hachage.

est appelé Pigeonhole principe .

D'autres ont indiqué pourquoi il ne fonctionnera pas. Je vais donc ajouter l'additif que le gain serait minime de toute façon.

Lorsque vous comparez deux chaînes en Java, la chaîne est égale à la fonction vérifie d'abord si elles sont deux références au même objet. Si oui, il retourne immédiatement vrai. Ensuite, il vérifie si les longueurs sont égales. Dans le cas contraire, il retourne faux. Seulement il commence à comparer caractère par caractère.

Si vous manipulez des données en mémoire, le même objet peut comparer rapidement gérer le « même » cas, et qui est un moyen rapide, humm, nombre entier de 4 octets comparer je pense. (Quelqu'un me corriger si j'ai la longueur d'un objet poignée mal.)

Pour les chaînes les plus inégales, je serais prêt à parier la longueur comparer les trouve rapidement pas égaux. Si vous comparez deux noms de choses - les clients, les villes, les produits, quelle que soit - ils ont généralement une longueur inégale. Donc, d'un simple int comparer dispose rapidement d'entre eux.

Le pire des cas, la performance va être deux longues, identiques, mais pas les mêmes chaînes d'objets. Ensuite, il doit faire la poignée objet COMPARE faux, garder le contrôle. La longueur comparer, vrai, garder le contrôle. Ensuite, caractère par caractère sur toute la longueur de la chaîne pour vérifier que oui, ils sont en effet égaux tout le chemin jusqu'à la fin.

Vous pouvez obtenir l'effet désiré à l'aide String.intern() (qui est mis en œuvre à l'aide d'une table de hachage.)

Vous pouvez comparer les valeurs de retour de intern() en utilisant l'opérateur ==. S'ils se réfèrent à la même chaîne, puis les cordes d'origine étaient équivalentes (à savoir equals() seraient retournés true), et il ne nécessite qu'une comparaison de pointeur (qui a le même coût qu'une comparaison de int.)

String a = "Hello";
String b = "Hel" + "lo";

System.out.println(a.equals(b));
System.out.println(a == b);

String a2 = a.intern();
String b2 = b.intern();

System.out.println(a2.equals(b2));
System.out.println(a2 == b2);

Sortie:

true
false
true
true

La valeur hashCode n'est pas unique, ce qui signifie que les chaînes ne peut pas réellement correspondre. Pour améliorer les performances, souvent mises en œuvre d'égaux effectuera une vérification hashCode avant d'effectuer des contrôles plus laborieux.

raison très simple: risque de collisions ... Un code de hachage aura beaucoup moins de valeurs possibles qu'une chaîne. Cela dépend un peu du genre de hachage que vous générez, mais nous allons prendre un exemple très simple, où vous ajouteriez les valeurs ordinales de lettres, multiplié par sa position: a = 1, b = 2, etc. Ainsi, « bonjour » serait traduire en: h: 8x1 = 8, e: 5x2 = 10, l: 12x3 = 36, l: 12x4 = 48, o: 15x5 = 75. 10 + 8 + 36 + 48 + 75 = 177.

Y at-il d'autres valeurs de chaîne qui pourrait finir comme 177 haché? Bien sûr! Beaucoup d'options. Ne hésitez pas à calculer quelques-uns.

Cependant, cette méthode de hachage utilisé une méthode simple. Java et .NET utiliser un algorithme de hachage plus complexe avec beaucoup moins de chances de ces collisions. Mais encore, il y a une chance que deux chaînes différentes se traduira par la même valeur de hachage, donc cette méthode est moins fiable.

Deux différentes chaînes peuvent facilement générer même code de hachage ou code de hachage différent. Si tu veux un code de hachage de test d'égalité ne donnera pas un résultat unique. Lorsque nous utilisons la classe String, il retournera valeur différente du code de hachage. Ainsi, la classe tampon chaîne doit être appliquer à avoir le même code de hachage pour chaque objet concated.

Il n'y a aucune raison de ne pas utiliser hashCode que vous décrivez.

Cependant, vous devez être au courant des collisions. Il y a une chance - une petite chance il est vrai - que deux chaînes différentes font hachage à la même valeur. Pensez à faire un hashCode au début, et en cas d'égalité font aussi la comparaison complète avec les égaux ().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top