Treemap忽略了我对equals函数的覆盖

时间:2012-03-16 19:04:03

标签: java treemap

我有一个TreeMap,其中RobotKey是一个由字符串字段域和长字段时间戳组成的类。 RobotKey具有如下可比性:

@Override
public boolean equals(Object obj) {
    if (this.domain.equals(((RobotKey) obj).getDomain()))
        return true;
    return false;
}

树图根据以下compareTo函数排序:

@Override
public int compareTo(RobotKey arg0) {
    if (this.lastAccessed < arg0.lastAccessed)
        return -1;
    else if (this.domain.equals(arg0.getDomain()))
        return 0;
    else
        return 1;
}

基本上,地图是通过域名访问的,并根据时间戳进行排序。

我做了treemap.get(RobotKey e),其中e与treemap中的现有条目具有相同的域名,但具有不同的时间戳。这应该返回正确的RobotValue,因为Map操作是用equals完成的。但它反而返回null表示找不到RobotKey。知道为什么会这样吗?我做错了什么,我该如何解决?谢谢!

2 个答案:

答案 0 :(得分:5)

问题是你的equals和compareTo方法的不一致。 当且仅当compareTo返回true时,equals必须返回0,据我所知,TreeMap(或TreeSet)不会调用equals方法,它只使用compareTo及其结果表示重复的密钥。

答案 1 :(得分:2)

每当你覆盖equals时,你也应该覆盖hashCode。

the documentation中查看equals和hashCode的合同,其中If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.

您的实现已损坏,因为映射使用hashCode来确定对象所属的存储桶,然后THEN可以使用equals来确定对象是否在存储桶中。在您的情况下,您认为相同的两个对象会生成不同的哈希码,因此集合不会在同一个桶中查找。