1

グラフにいくつかのエッジを格納する HashSet があります。各エッジには 2 つのノードがあります。

グラフが無向の場合、複製の追加は失敗するはずです。

Edge a = new Edge(new Node("aa"), new Node("bb"));
Edge duplicate = new Edge(new Node("aa"), new Node("bb"));

ただし、次の例では機能します。

System.out.println(a.equals(duplicate));

Set<Edge> sete = new HashSet<Edge>();
System.out.println(sete.contains(a));
System.out.println(sete.add(a));
System.out.println(sete.contains(duplicate));
System.out.println(sete.add(duplicate));

Output:
true

false
true
false
true

編集: さて、有向エッジで機能する hashCode メソッドを追加しました。無向エッジのハッシュを計算するのを手伝ってくれる人はいますか?

public class Edge {
    private Node first, second;

    @Override
    public /boolean equals(Object ob) {
        if (ob instanceof Edge) {
            Edge edge = (Edge) ob;
            if (first.equals(edge.first)
                    && second.equals(edge.second)
                    || first.equals(edge.second)
                    && second.equals(edge.first))
                return true;
        }
        return false;
   }


    @Override
    public int hashCode() {
        int hash = 17;
        int hashMultiplikator = 79;
        hash = hashMultiplikator * hash
                + first.hashCode();
        hash = hashMultiplikator * hash
                + second.hashCode();
        return hash;
    }
4

2 に答える 2

5

コメントで述べたように...

との両方のクラスに対して.equals()とを実装する必要があります。.hashCode()EdgeNode

は、新しいエントリを配置するハッシュ バケットを決定するためにHashSet使用します。.hashCode()このバケットにすでにエントリがある場合は.equals()、バケットの各エントリで を使用して、エントリが既に存在するかどうかを確認します。

それらのいずれもオーバーライドしなかったため、これらのメソッドの実装は次のいずれかになりますObject

  • .hashCode()オブジェクトの参照アドレスに対する単純なハッシュです。
  • .equals()両方のオブジェクトが同じ参照 (つまり ) である場合にのみ true ですo1 == o2

そして、これは明らかにあなたが望むものではありません!

于 2013-06-07T09:02:00.273 に答える
1

このフォノメノンの唯一の説明は、Edge.hashCode が正しくないかオーバーライドされていないことです。これらの行をコードに追加する必要があります

System.out.println(a.hashCode());
System.out.println(duplicate.hashCode());

理由を知る

于 2013-06-07T09:04:22.347 に答える