Java 树映射忽略我对equals函数的重写

Java 树映射忽略我对equals函数的重写,java,treemap,Java,Treemap,我有一个树形图,其中RobotKey是一个由字符串域和长字段时间戳组成的类。RobotKey实现了如下功能: @Override public boolean equals(Object obj) { if (this.domain.equals(((RobotKey) obj).getDomain())) return true; return false; } 树状图根据以下比较函数进行排序: @Override public int compareTo(R

我有一个树形图,其中RobotKey是一个由字符串域和长字段时间戳组成的类。RobotKey实现了如下功能:

@Override
public boolean equals(Object obj) {
    if (this.domain.equals(((RobotKey) obj).getDomain()))
        return true;
    return false;
}
树状图根据以下比较函数进行排序:

@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;
}
@覆盖
公共int比较(机器人钥匙arg0){
if(this.lastAccessed
因此,基本上,地图是通过域名访问的,并根据时间戳进行排序


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

无论何时重写equals,都应该重写hashCode

查看equals和hashCode的合同,其中说
如果两个对象根据equals(Object)方法相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果。


您的实现被破坏,因为映射使用hashCode来确定对象属于哪个bucket,然后可能使用equals来确定对象是否在bucket中。在您的情况下,您认为相等的两个对象生成不同的哈希代码,因此集合不会在同一个桶中查找。

任何时候重写相等,也应该重写哈希代码。

查看equals和hashCode的合同,其中说
如果两个对象根据equals(Object)方法相等,那么对两个对象中的每一个调用hashCode方法必须产生相同的整数结果。


您的实现被破坏,因为映射使用hashCode来确定对象属于哪个bucket,然后可能使用equals来确定对象是否在bucket中。在你的情况下,你认为相等的两个对象生成不同的哈希代码,所以集合不是在同一个桶中寻找的。

问题是关于你的相等和比较方法的不一致性。


compareTo
必须返回0当且仅当
equals
返回true时,就我所知,TreeMap(或TreeSet)没有调用
equals
方法,它只是使用
compareTo
及其结果来指示重复的键。

问题在于equals和compareTo方法的不一致性。
compareTo
必须返回0当且仅当
equals
返回true时,就我所知,TreeMap(或TreeSet)没有调用
equals
方法,它只是使用
compareTo
及其结果来指示重复的键。

据我所知,TreeMap不是一个基于哈希的映射,我只是试图重写hashcode函数以返回域字符串的hashcode,但这不起作用。我知道,TreeMap和TreeSet不会对它们包含的对象调用
equals
方法。啊,我没有专门研究TreeMap。在任何情况下,违反equals/hashCode契约都是不好的。在这种情况下,你有一个很好的观点,我将投票支持你的答案,因为它解决了当前的问题。完全同意,
等于
hashCode
应该是一致的,因为谁能保证该对象永远不会存储在HashMap中,HashSet?顺便说一句,
equals
compareTo
也应该是一致的,因为TreeSet和TreeMap的原因是一样的。据我所知TreeMap不是一个基于哈希的映射Yea,我只是尝试重写hashcode函数来返回域字符串的hashcode,但这不起作用。我知道,TreeMap和TreeSet不会对它们包含的对象调用
equals
方法。在任何情况下,违反equals/hashCode契约都是不好的。在这种情况下,你有一个很好的观点,我将投票支持你的答案,因为它解决了当前的问题。完全同意,
等于
hashCode
应该是一致的,因为谁能保证该对象永远不会存储在HashMap中,HashSet?顺便说一下,
equals
compareTo
也应该是一致的,因为TreeSet和TreeMap的原因相同。嗨,我的compareTo和我的equals函数是一致的。在这两个函数中,如果域名是相同的字符串,则返回0或true。但我想你可能是对的,你看到我遗漏了什么矛盾吗?哦,事实上我看到了我的问题。返回0位于my else if语句中,如果if为true,则可能不会调用该语句。您必须使其在
上次访问
方面保持一致。现在,如果域不同,但上次访问的
是相等的,则返回
1
,这是错误的。您好,我的compareTo和我的equals函数是一致的。在这两个函数中,如果域名是相同的字符串,则返回0或true。但我想你可能是对的,你看到我遗漏了什么矛盾吗?哦,事实上我看到了我的问题。返回0位于my else if语句中,如果if为true,则可能不会调用该语句。您必须使其在
上次访问
方面保持一致。现在,如果域不同,但上次访问的
相同,则返回
1
,这是错误的。