Problème HashSet & # 8212; est égal à et hashCode avec contient travaille différemment que ce à quoi je m'attendais

StackOverflow https://stackoverflow.com/questions/230585

Question

J'ai le code suivant:

class IncidentTag:
     def __init__(self,tag):
        self.tag = tag
     def equals(self,obj):
        return self.tag.equals(obj.tag)
     def hashCode(self):
        return self.tag.hashCode()

from java.lang import String
from java.util import HashMap
from java.util import HashSet

tag1 = IncidentTag(String("email"))
tag1copy = IncidentTag(String("email"))
tag2 = IncidentTag(String("notemail"))

print tag1.equals(tag1copy)
print tag2.equals(tag2)

print "Now with HashSet:"

hSet = HashSet()
hSet.add(tag1)
hSet.add(tag2)

print hSet.contains(tag1)
print hSet.contains(tag2)
print hSet.contains(tag1copy)

La sortie est: 1 1 Maintenant avec HashSet: 1 1 0

Cependant, je me serais attendu à ce que la dernière ligne soit vraie (1) également. Y a-t-il quelque chose d'évident qui me manque.

(oui, je sais que ma méthode equals et mes méthodes de hashcode ne prennent pas en compte certains problèmes ... elles sont délibérément simples, mais laissez-moi savoir si les problèmes qui vous causent sont à l'origine de ce problème)

Était-ce utile?

La solution

Vous ne devriez pas implémenter les méthodes Java-Style equals et hashCode, mais les équivalents Python __ eq __ et __ hash __ . Ajout de

def __hash__(self):
    return self.hashCode()
def __eq__(self, o):
    return self.equals(o)

aide. Autant que je sache, ces méthodes python sont liées dynamiquement à hashCode et à equals () par Jython. Cela garantit que vous pouvez insérer des classes Python dans les collections de Java.

Le code affiche cinq "1".

Autres conseils

J'ai écrit un code équivalent en Java et il produit true pour les trois appels contient (). Je pense donc que cela doit être une curiosité dans Jython. Peut-être que les objets Java sous-jacents ne sont pas exactement ce que vous voyez en Python.

Je ne connais pas Python, mais il semble que les objets equals () et hashcode () de l'objet Java sous-jacent ne respectent pas le contrat requis.

  • Deux objets si equals () doivent renvoyer le même hashcode ().

On dirait que c'est violé. Les hachages vont d'abord utiliser le hashcode dans la recherche pour obtenir la liste dans laquelle l'objet correspondant serait, puis parcourir la liste pour trouver celui qui est égal. Si votre code de hachage n'honore pas le contrat et qu'il renvoie des codes de hachage différents, il ne le trouvera pas dans le hachage, même s'il était comparable ().

Le code Java Object.hashcode () par défaut ne renverra pas le même code de hachage pour 2 objets. Vous devez le remplacer.

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