3

私は次のコードを持っています:

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)

出力は次のとおりです。11HashSetを使用:1 1 0

ただし、最終行もtrue(1)になると思っていました。私が行方不明になっている明らかな何かがありますか。

(はい、私のequals方法とhashcode方法はいくつかの問題を考慮に入れていないことを知っています...それらは意図的に単純ですが、そこにある問題がこの問題を引き起こしている場合は私に知らせてください。)

4

3 に答える 3

10

JavaスタイルのequalsメソッドとhashCodeメソッドを実装するのではなく、Pythonの同等のメソッドとを実装する必要が__eq__あり__hash__ます。追加する

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

役立ちます。これらのPythonメソッドは、私が知る限り、JythonによってhashCodeとequals()に動的にバインドされています。これにより、PythonクラスをJavaのコレクションに入れることができます。

これで、コードは5つの「1」を出力します。

于 2008-10-23T18:16:54.130 に答える
1

私は Java で同等のコードを書きましたが、3 つの contains() 呼び出しすべてに対して true を生成します。したがって、これは Jython では奇妙に違いないと思います。おそらく、基礎となる Java オブジェクトは、Python で見られるものとまったく同じではありません。

于 2008-10-23T17:33:01.753 に答える
0

Python についてはわかりませんが、基礎となる Java オブジェクトの equals() と hashcode() が必要な契約を尊重していないようです。

  • equals() が同じ hashcode() を返さなければならない場合、2 つのオブジェクト。

違反しているようです。HashSet は、最初にルックアップでハッシュコードを使用して、一致するオブジェクトが含まれるリストを取得し、次にリストを調べて等しいものを見つけます。ハッシュコードがコントラクトを尊重しておらず、異なるハッシュコードを返している場合、equals() に匹敵するものであっても、ハッシュセットでそれを見つけることはできません。

デフォルトの Java Object.hashcode() は、2 つのオブジェクトに対して同じハッシュコードを返しません。それをオーバーライドする必要があります。

于 2008-10-23T22:18:48.697 に答える