设置包含和对象相等

时间:2014-01-31 12:06:54

标签: java set equals

我不明白为什么HashSet上的contains()在以下示例中返回false:

import java.util.HashSet;
import java.util.Set;

public class MyMatching {

    private Integer[] id;

    public MyMatching(Integer id1, Integer id2) {
        this.id = new Integer[2];
        id[0] = id1;
        id[1] = id2;
    }

    public String getId() {
        return id[0] + ":" + id[1];
    }

    @Override
    public boolean equals(Object other) {
        if (this == other)
            return true;
        if (other == null || (this.getClass() != other.getClass())) {
            return false;
        }
        MyMatching otherMatching = (MyMatching) other;
        return (getId().equals(otherMatching.getId()));
    }

    @Override
    public int hashCode() {
        int result = 31 * id.hashCode();
        return result;
    }

    public static void main(String[] args) {
        MyMatching matching1 = new MyMatching(1571021585, 848339230);
        MyMatching matching2 = new MyMatching(661883516, 310961952);
        Set<MyMatching> matchings = new HashSet<>();
        matchings.add(matching1);
        matchings.add(matching2);

        MyMatching testMatching = new MyMatching(1571021585, 848339230);
        System.out.print("HashSet contains testMatching: ");
        System.out.println(matchings.contains(testMatching));

        Object[] matchingsArray = matchings.toArray();
        for (Object o : matchingsArray) {
            System.out.print("Object equals testMatching: ");
            System.out.println(o.equals(testMatching));
        }
    }
}

结果是:

HashSet contains testMatching: false
Object equals testMatching: false
Object equals testMatching: true

Set's contain method的文档是:

  

如果此set包含指定的元素,则返回true。更正式地,如果&gt;返回true并且只有当这个集合包含一个元素e时(o == null?e == null:o.equals(e))。

我的问题:为什么contains()在Set上返回false,但equals()在对象上返回true?

1 个答案:

答案 0 :(得分:6)

hashCode的实现与equals不一致:id是一个数组,它不会根据数组中保存的值计算哈希码。

为了正确实现,您可以返回生成的ID字符串的哈希码:

@Override
public int hashCode() {
    return getId().hashCode();
}

或者您可以直接根据数组值计算哈希码,例如:

@Override
public int hashCode() {
    return id[0] ^ id[1];
}