什么问题/陷阱,必须重写时,必须考虑equals和hashCode?
类Enum中的方法hashCode()是final,定义为super.hashCode(),这意味着它根据实例的地址返回一个数字,该数字是来自程序员POV的随机数.
将其定义为例如ordinal() ^ getClass().getName().hashCode()跨不同JVM的确定性.它甚至可以更好地工作,因为最低有效位会"尽可能地改变",例如,对于包含多达16个元素的枚举和大小为16的HashMap,肯定没有碰撞(当然,使用EnumMap更好,但有时不可能,例如没有ConcurrentEnumMap).根据目前的定义,你没有这样的保证,对吗?
使用Object.hashCode()比较如上所述的更好的hashCode,如下所示:
HashSet迭代顺序搜寻错误我个人更喜欢更好的hashCode,但恕我直言,没有理由权重,可能除了速度.
我对速度感到好奇并写了一个令人惊讶的结果的基准.对于每个类的单个字段的价格,您可以使用确定性哈希码,其速度快近四倍.将哈希码存储在每个字段中会更快,尽管可以忽略不计.

标准哈希码不快得多的原因是它不能成为对象的地址,因为对象被GC移动了.
一般来说,表演会有一些奇怪的事情发生hashCode.当我理解它们时,仍然存在未解决的问题,为什么System.identityHashCode(从对象标题读取)比访问普通对象字段慢.
我有一个名为User的域对象.用户的属性包括ssoId,name,email,createdBy,createdDate和userRole.其中,ssoId必须是唯一的,因为没有两个用户可以拥有相同的sso id.所以我的equals方法检查sso id并返回true或false.
@Override public boolean equals(Object o) {
if (!(o instanceof User))
return false;
return user.getSsoId().equals((User)o.getSsoId());
}
Run Code Online (Sandbox Code Playgroud)
我觉得这是一个不正确的实现,尽管就业务规则而言是正确的.对于具有相同sso id但具有不同的名称或电子邮件或两者的值的两个对象,上述实现将返回true.我应该更改我的平等合同以检查所有字段的相等性吗?你的建议是什么?
我有一个枚举类如下.
public enum Item {
COKE("Coke", 25), PEPSI("Pepsi", 35), SODA("Soda", 45);
private String name;
private int price;
private Item(String name, int price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public long getPrice() {
return price;
}
}
Run Code Online (Sandbox Code Playgroud)
以及如下定义的散列映射
private Map<Item, Integer> inventory = new HashMap<Item, Integer>();
Run Code Online (Sandbox Code Playgroud)
我是否需要重写了hashCode和枚举等于Item类inventory.put()和inventory.get()正常工作?如果没有,为什么?