1

intSetデータ構造を含むSetObという名前の単純なプライベート クラスを定義しました。「メイン」メソッドにSetObをキーとして、Integer を値として持つ HashMap があります。メイン メソッドでわかるように、HashMap にSetObインスタンスをフィードし、まったく同じ値を持つインスタンスを探すと、「null」が返されます。これは、HashMap のキーとしてSetObのような独自の定義済みデータ構造を使用する前に、かなりの回数発生しました。誰かが私に欠けているものを指摘してもらえますか? SetOb クラスのコンストラクターでは、引数として渡された Set をコピーすることに注意してください。

public class Solution {

    public static Solution sample = new Solution();
    private class SetOb {
        public int last;
        public Set<Integer> st;
        public SetOb(int l , Set<Integer> si ){
            last = l;
            st = new HashSet<Integer>(si);
        }
    }

    public static void main(String[] args) {
        Map<SetOb, Integer> m = new HashMap< SetOb, Integer>();
        Set<Integer> a = new HashSet<Integer>();

        for(int i =0; i<10; i++){
            a.add(i);
        }
        SetOb x = sample.new SetOb(100, a);
        SetOb y = sample.new SetOb(100, a);
        m.put(x,500);
        Integer val = m.get(y);
        if(val!= null) System.out.println("Success: " + val);
        else System.out.println("Failure");
    }

}
4

3 に答える 3

2

あなたxy は同じオブジェクト インスタンスではないため、 と を一致させることができず、マップ内で一致するキー/値を見つけることができませんyx

マッチングを成功させたい場合は、フィールド値を比較するメソッドを実装(オーバーライド)hasCodeしてequalsください。SetOb

以下のサンプルメソッド(Eclipse生成):

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + last;
    result = prime * result + ((st == null) ? 0 : st.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    SetOb other = (SetOb) obj;
    if (last != other.last)
        return false;
    if (st == null) {
        if (other.st != null)
            return false;
    } else if (!st.equals(other.st))
        return false;
    return true;
}
于 2012-11-05T02:24:58.653 に答える
2

SetObメソッドをオーバーライドする必要がhashCode()ありますequals()

ハッシュベースのコレクションは、これらのメソッドを使用してオブジェクトを保存 ( hashCode()) および取得 ( hashCode()) しequals()ます。

于 2012-11-05T02:26:06.673 に答える
2

の既定の実装でhashCodeは、オブジェクト IDを使用してハッシュ コードを決定します。値 identityが必要な場合は、プライベート クラスにhashCode(および)を実装する必要があります。例えば:equals

private class SetOb {
    public int last;
    public Set<Integer> st;
    public SetOb(int l , Set<Integer> si ){
        last = l;
        st = new HashSet<Integer>(si);
    }
    @Override
    public boolean equals(Object other) {
        if (other.class == SetOb.class) {
            SetOb otherSetOb = (SetOb) other;
            return otherSetOb.last == last && otherSetOb.st.equals(st);
        }
        return false;
    }
    @Override
    public int hashCode() {
        return 37 * last + st.hashCode();
    }
}
于 2012-11-05T02:26:49.937 に答える