java中的HashMap不能哈希MyObject

时间:2012-11-05 02:21:04

标签: java hashmap hashset

我定义了一个名为 SetOb 的简单私有类,其中包含 int Set 数据结构。我在'main'方法中有一个HashMap,其中 SetOb 为Key,Integer为value。现在您可以在main方法中看到,当我使用 SetOb 实例提供HashMap,然后查找具有完全相同值的实例时,它将返回'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");
    }

}

3 个答案:

答案 0 :(得分:2)

您的xy 不是相同的对象实例因此包含的y无法与x匹配,最终没有在地图中找到匹配的键/值。

如果您希望匹配成功,请执行(覆盖)hasCode&amp; 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;
}

答案 1 :(得分:2)

SetOb需要覆盖hashCode(),因此需要覆盖equals()方法。

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

答案 2 :(得分:2)

hashCode的默认实现使用对象标识来确定哈希码。如果您需要值标识,则需要在私有类中实现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();
    }
}