即使hashCode / equals被覆盖,HashMap也会返回null

时间:2015-06-03 21:57:48

标签: java hashmap

我有一个将自定义对象TokenDocumentPair映射到Double的HashMap。 TokenDocumentPair如下:

  static class TokenDocumentPair {
    int documentNum;
    String token;
    public TokenDocumentPair(String token, int documentNum) {
      this.token = token;
      this.documentNum = documentNum;
    }

    public boolean equals(TokenDocumentPair other) {
      return (this.documentNum == other.documentNum && this.token.equals(other.token));
    }

    public int hashCode() {
      int result = 1;
      result = 37 * result + Objects.hashCode(this.documentNum);
      result = 37 * result + Objects.hashCode(this.token);
      return result;
    }

    public String toString() {
      return String.format("[Document #%s, Token: %s]", documentNum, token);
    }
  }

问题是,当我创建TokenDocumentPair pair1 = new TokenDocumentPair("hello", 1)时,将其存储到HashMap<TokenDocumentPair, Double> map,然后尝试使用TokenDocumentPair pair2 = new TokenDocumentPair("hello", 1)获取它,它会返回null。但是,我的印象是,由于我的hashcode和equals方法匹配并且基于存储的两个字段,哈希映射将能够找到原始pair1并将其值返回给我。

TokenDocumentPair pair1 = new TokenDocumentPair("hello", 1);
TokenDocumentPair pair2 = new TokenDocumentPair("hello", 1);
assert pair1.hashCode() == pair2.hashCode(); // ok
assert pair1.equals(pair2); // ok

HashMap<TokenDocumentPair, Double> map = new HashMap<>();
map.put(pair1, 0.0);
map.get(pair2); // null
map.containsKey(pair2); // false

我在这里做错了什么?

1 个答案:

答案 0 :(得分:5)

equals方法未被覆盖。你已经超负荷了。

要覆盖的方法Object#equals的签名必须如下所示:

@Override
public boolean equals(Object o) {
    //...
}

为了确保您重写方法,请在声明方法时使用@Override注释。如果将此批注添加到当前的equals方法,则会出现编译器错误和正确的错误消息。