HashSet Problem - gleich und hashCode mit enthält funktioniert anders, als ich erwarten würde

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

Frage

Ich habe den folgenden Code:

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)

Die Ausgabe lautet: 1 1 Jetzt mit HashSet: 1 1 0

Allerdings würde ich die letzte Zeile um wahr zu sein erwartet (1) als auch. Gibt es etwas offensichtlich, dass ich fehle.

(ja, ich weiß, dass meine Methode equals und hashCode Methoden nicht nehmen einige Probleme zu berücksichtigen ... sie sind bewusst einfach, aber lassen Sie mich wissen, ob die Probleme dadurch verursacht dieses Problem)

War es hilfreich?

Lösung

Sie sollten nicht implementiert der Java-Style entspricht und hashCode Methode, sondern der Python equivaltents __eq__ und __hash__. Hinzufügen

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

hilft. Diese Python Methoden sind - soweit ich weiß - dynamisch gebunden hashCode und equals () von Jython. Dies stellt sicher, dass Sie Python-Klassen in Java-Kollektionen setzen können.

Jetzt ist der Code gibt fünf "1".

Andere Tipps

Ich schrieb entsprechenden Code in Java und es produziert gilt für all drei enthält () Anrufe. Also ich denke, das in Jython eine Kuriosität sein muss. Vielleicht sind die zugrunde liegenden Java-Objekte nicht genau das, was Sie sehen, wie sie, wie in Python.

Ich weiß nicht, Python, aber es sieht aus wie sicher das zugrunde liegende Java-Objekt equals () und hashCode () sind den erforderlichen Vertrag nicht ehren.

  • Zwei Objekte, wenn equals () muß den gleichen Hash-Code () zurückgeben.

Es sieht aus wie das verletzt wird. HashSets werden zuerst die Hash-Code in der Suche verwendet werden um die Liste das passende Objekt in dann wäre zu bekommen, die Liste durchgehen, das zu finden, die gleich ist. Wenn Ihr hashcode ist, den Vertrag nicht zu ehren und sie unterschiedliche Hashcodes sind Rückkehr, dann wird es nicht in der Hashset finden, auch wenn sie Gleichen waren () vergleichbar.

Der Standard-Java Object.hashCode () wird nicht den gleichen Hash-Code für 2 Objekte zurückzukehren. Du hast es außer Kraft zu setzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top