我有一个枚举类,如下。
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;
}
}
以及定义如下的哈希图
private Map<Item, Integer> inventory = new HashMap<Item, Integer>();
我是否需要重写枚举
Item
类中的 hashcode 和 equals 才能使 inventory.put()
和 inventory.get()
正常工作?如果没有,为什么?
不,你不知道。为什么?因为已经提供了这些方法的合理实现。
即使你想,你也做不到,因为这些方法是枚举中的
final
。
但是,不要将
HashMap
与枚举键类型一起使用:使用 EnumMap
,它专门用于枚举键,并且不使用 hashCode
或 equals
(它实际上使用 ordinal
)。
编辑:阅读完Enum.hashCode背后的原因是什么后,我注意到
hashCode
和equals
的实现实际上是来自Object
的实现。但这些是合理的,因为枚举值的不可实例化。
如果您无法创建枚举值的新实例,则使用这些默认值没有问题:
这篇文章是不久前写的,但我认为值得添加一些关于 enum hashCode() 的内容,这让我绊倒了......
枚举的 hashCode 在程序启动时是固定的,因为枚举本质上只是一个静态对象,因此 Object.hashCode() 将在程序运行期间返回相同的值。
但是,下次程序运行时,这很可能不是内存中的同一地址。
枚举是通过其在内存中的地址 (==) 进行比较(与 equals 进行比较),而不是通过 equals() 进行比较。这就是为什么 hashCode() 必须做同样的事情,或者正如文档所说的“类似的东西”(或多或少)。
如果您有其他包含枚举的类,并且您从 IDE 自动为其生成哈希码,则该新类的哈希码将取决于您运行代码的时间。如果这个其他类被持久化,它的哈希码在程序启动时将不相等。
如果您希望枚举哈希码始终保持不变,请对枚举的字符串进行哈希处理。这样,只有当有人更改枚举的字符串值时,它才会发生变化,并且还满足 Java 的 hashCode/equals() 契约要求。