Set<> .contains和hashCode的问题

时间:2013-07-09 09:10:53

标签: java set hashcode

我有一个Set<SelectDTO>只有一个元素,当我使用.contains和一个新的SelectDTO时我失败了,如下所示:

Set<SelectDTO> setDTOs = new HashSet<SelectDTO>
//processing where an element with <name = "ME101", id = 102> is added.

SelectDTO selectDTO = new SelectDTO();
selectDTO.setName("ME101");
selectDTO.setId(102);
if (!setDTOs.contains(selectDTO)){
     throw new Exception();
}

我覆盖了SelectDTO的.hashCode(),因此它被计算为参数id和name的总和。我已经调试并确认执行两次.hashCode():第一次将元素添加到集合中,第二次调用.contains()时。两个元素的hashCode是-2024486876。但是,在调试时,我看到集合中的表有一个单独的元素,它的“哈希”是-1909995738。

这是我的hashCode的代码,虽然我认为问题不在那里:

@Override
public int hashCode() {
    int result = 0;
    result += this.getName() != null ? this.getName().hashCode() : 0;
    result += this.getId() != null ? this.getId() : 0;
    return result;
}

我猜.contains()正在使用此'哈希'值进行比较,但我不知道原因。

2 个答案:

答案 0 :(得分:4)

来自Set.contains() documentation

  

如果此set包含指定的元素,则返回true。更正式的是,当且仅当此集合包含true元素e时才返回(o==null ? e==null : o.equals(e))

换句话说,您不仅需要实施hashCode(),还需要实施equals()

答案 1 :(得分:0)

您似乎忘了在Set:

中添加selectDTO元素
setDTOs.add(selectDTO);

假设您已在代码中的某处添加了元素,那么您需要覆盖equals方法而不是hashCode。由于contains()方法使用equals()方法来确定集合中是否存在元素。有趣的是,我相信这就是Set确保它不会在Set中推送重复元素。