1

我定义了一个名为SetOb的简单私有类,其中包含一个int和一个Set数据结构。我在“主”方法中有一个 HashMap,其中SetOb作为键,整数作为值。现在,正如您在 main 方法中看到的那样,当我为 HashMap 提供一个SetOb实例,然后查找具有完全相同值的实例时,它返回“null”。在我使用自己定义的数据结构(如SetOb)作为 HashMap 中的 Key 之前,这种情况已经发生过好几次了。有人可以指出我错过了什么吗?请注意,在 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 不是同一个对象实例,因此 contains 无法匹配yx最终无法在 Map 中找到匹配的键/值。

如果您希望匹配成功,请实现(覆盖)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需要覆盖 thehashCode()equals()方法。

基于散列的集合使用这些方法来存储(hashCode())和检索(hashCode())和equals())您的对象。

于 2012-11-05T02:26:06.673 回答
2

默认实现hashCode使用对象标识来确定哈希码。如果您想要价值标识,您将需要在您的私有类中实现hashCode(and ) 。例如: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 回答