21

我有一个关于TreeSet集合和hashCode方法的快速问题。我有一个TreeSet并且我正在向它添加对象,在添加对象之前,我检查它是否存在于TreeSetusingcontains方法中。

我有 2 个不同的对象,每个对象都使用我的 hashCode 方法实现产生一个不同的 hashCode,示例如下:

public int hashCode()
{
    int hash = 7;
    hash = hash * 31 + anAttribute.hashCode();
    hash = hash * 31 + anotherAttribute.hashCode();
    hash = hash * 31 + yetAnotherAttribute.hashCode();
    return hash;
}

特定运行的哈希码是:76126352 和 76126353(对象在一个属性中仅相差一位)。

对于这些对象, contains 方法返回 true,即使 hashCode 不同。任何想法为什么?这真的很令人困惑,我们将不胜感激。

4

4 回答 4

47

TreeSet 根本不使用hashCode。它使用compareTo或您传递给构造函数的 Comparator。诸如 contains 之类的方法使用它来查找集合中的对象。

所以你的问题的答案是你的 compareTo 方法或你的 Comparator 被定义为使有问题的两个对象被认为是相等的。

从javadocs:

TreeSet 实例使用其 compareTo(或 compare)方法执行所有元素比较,因此从集合的角度来看,此方法认为相等的两个元素是相等的。

于 2009-09-24T10:06:58.593 回答
4

来自 Java 文档:

如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。

意味着:您用于散列的对象不相等。

于 2009-09-24T10:01:25.903 回答
0

您需要阅读 Joshua Bloch 的“Effective Java”第 3 章。它解释了 equals 合约以及如何正确覆盖 equals、hashCode 和 compareTo。

于 2009-09-24T10:10:47.543 回答
0

您不需要检查它是否被包含,因为 insert() 在到达插入点的途中基本上会执行相同的操作(即搜索正确的位置)。如果无法插入对象(即对象已被包含),则 insert 返回 false。

于 2010-03-29T13:46:38.960 回答