Java HashSet问题——equals和hashCode与contains的工作方式不同于I';我希望

Java HashSet问题——equals和hashCode与contains的工作方式不同于I';我希望,java,collections,jython,hashset,Java,Collections,Jython,Hashset,我有以下代码: 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

我有以下代码:

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)
输出为: 1. 1. 现在使用HashSet: 1. 1. 0

然而,我本以为最后一行也是
true
(1)。有什么明显的东西我遗漏了吗


(是的,我知道我的
equals
方法和
hashcode
方法没有考虑到一些问题……它们非常简单,但一定要让我知道这些问题是否导致了这个问题。)

我用Java编写了等效的代码,并且它确实为所有三个contains()调用生成了true。所以我认为这在Jython一定是个奇怪的现象。可能底层Java对象与Python中的对象并不完全相同。

您不应该实现Java风格的equals和hashCode方法,而应该实现Python的equalts和hashCode方法。添加

def __hash__(self):
    return self.hashCode()
def __eq__(self, o):
    return self.equals(o)
有帮助。 据我所知,这些python方法由Jython动态绑定到hashCode和equals()。这确保您可以将Python类放入Java集合中


现在代码打印出五个“1”。

我不懂Python,但看起来底层Java对象的equals()和hashcode()显然没有遵守所需的约定

  • 两个对象if equals()必须返回相同的hashcode()
看起来这是违反规定的。hashset首先要在查找中使用hashcode来获取匹配对象所在的列表,然后遍历该列表以找到相等的列表。如果您的hashcode不遵守合同,并且他们返回了不同的hashcode,那么即使它们是equals()可比的,它也不会在hashset中找到它


默认的Java Object.hashcode()不会为两个对象返回相同的hashcode。你必须重写它。

我也用Java写了同样的代码,结果和Dave Costa一样。这太奇怪了。我猜语言绑定是这样的,但我在任何地方都没有看到这方面的文档。无论如何,这确实解决了问题。。。谢谢