使用HashMap和自定义键

MBZ*_*MBZ 7 java map

快速问题:如果我想使用HashMap自定义类作为键,我必须覆盖该hashCode函数吗?如果我不重写该功能,它将如何工作?

Pet*_*rey 5

如果您不覆盖 hashCode AND equals,您将获得默认行为,即每个对象都不同,无论其内容如何。

  • 除非他正在扩展具有适合他的 hashCode 的东西 (2认同)

Puc*_*uce 4

从技术上讲,只要相等的对象具有相同的 hashCode,就不必重写 hashCode 方法。

因此,如果您使用 Object 定义的默认行为,其中 equals 仅对同一实例返回 true,那么您不必重写 hashCode 方法。

但如果您不重写 equals 和 hashCode 方法,则意味着您必须确保始终使用相同的键实例。

例如:

MyKey key1_1 = new MyKey("key1");

myMap.put(key1_1,someValue); // OK

someValue = myMap.get(key1_1); // returns the correct value, since the same key instance has been used;

MyKey key1_2  = new MaKey("key1"); // different key instance

someValue = myMap.get(key1_2); // returns null, because key1_2 has a different hashCode than key1_1 and key1_1.equals(key1_2) == false
Run Code Online (Sandbox Code Playgroud)

在实践中,您通常只有一个键实例,因此从技术上讲,您不必重写 equals 和 hashCode 方法。

但无论如何,最佳实践是重写用作键的类的 equals 和 hashCode 方法,因为稍后您或其他开发人员可能会忘记必须使用相同的实例,这可能导致难以跟踪问题。

请注意:即使您重写 equals 和 hashCode 方法,也必须确保不会以会更改 equals 或 hashCode 方法结果的方式更改键对象,否则映射将找不到您的值不再了。这就是为什么建议尽可能使用不可变对象作为键。