根据hashCode
/ equals
合同,如果两个对象相等,则必须具有相同的hashCode
- 至少这是我所知道的。请考虑以下实现:
package Happy;
import java.time.LocalDate;
class MyClass
{
private int id;
public int getId()
{
return id;
}
public MyClass(int id)
{
this.id = id;
}
public int hashCode()
{
return LocalDate.now().getYear() + getId();
}
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyClass other = (MyClass) obj;
if (hashCode() != other.hashCode())
return false;
return true;
}
}
public class HappyNewYear
{
public static void main(String[] args) {
MyClass my = new MyClass(0);
if (my.hashCode() != my.hashCode()) System.out.println("Happy New Year!");
}
}
经过少量修改,我们可以得到一个不太极端的变体:
public int hashCode()
{
return return (int) (System.nanoTime() + getId());
}
我测试了它(虽然不是getYear
),条件是真的(hashCodes
不相等)。
如果hashCode
随着时间的推移而改变,即使对象的字段未修改,这是否合法?我找不到有关此特定实现的任何资源。 我知道集合的问题,但我的问题是,根据合同/规范,hashCode实现是否合法。
equals
和hashCode
都满足于简单的合同。< / p>
答案 0 :(得分:2)
这是合法的(编译器不会抱怨它),但你不应该这样做。 HashCode
应该是一致的(给定相同的密钥返回相同的整数值)。
hashCode
方法必须始终返回相同的整数
你的hashCode
恰恰相反。
答案 1 :(得分:1)
由于哈希码用于放置然后查找存储在哈希映射中的对象,因此哈希码随时间变化的类将无法在哈希映射中使用。
答案 2 :(得分:0)
我认为如果.equals
方法失败,那么.hashcode
也会失败。
话虽这么说,如果两个对象昨天被认为是相等但现在却不是,那么它很可能会产生比它将要解决的问题更多的问题,因为就对象而言,它的所有字段都没有改变。 (想想运行数天的系统)。
我建议你让.hashcode()
依赖于对象本身,而不是改变并且在对象之外的东西。如果这不是一个选项,您需要大量记录。