在HashMap中设置键类型,如何?

yot*_*oto 2 java key hashmap

嗨,我想创建一个存储表达式(我创建的一个小对象)的 HashMap(java)。如何选择要使用的密钥类型?整数和字符串对我来说有什么区别?我想我只是不完全理解 HashMap 背后的想法,所以我不确定要使用什么键。谢谢!

Jac*_*ack 5

JavaHashMap依赖于两件事:

  • hashCode()方法返回一个从键生成并在映射内部使用的整数
  • equals(..)方法应该与计算的哈希值一致,这意味着如果两个键具有相同的哈希码,那么它们最好是相同的元素。

来自Java API 文档的具体要求如下:

  • 每当在 Java 应用程序执行期间对同一对象多次调用 hashCode 方法时,只要对象上的 equals 比较中使用的信息没有被修改,hashCode 方法就必须始终返回相同的整数。从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致。
  • 如果根据 equals(Object) 方法两个对象相等,则对这两个对象调用 hashCode 方法必须产生相同的整数结果。
  • 如果两个对象根据 equals(java.lang.Object) 方法不相等,则不要求对这两个对象中的每一个调用 hashCode 方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

如果您不提供任何类型的具体实现,则将使用对象的内存引用作为哈希码。这在大多数情况下通常都很好,但是如果您有以下情况:

Expression e1 = new Expression(2,4,PLUS);
Expression e2 = new Expression(2,4,PLUS);
Run Code Online (Sandbox Code Playgroud)

(我实际上不知道你需要在哈希图中放置什么,所以我只是猜测)

然后,由于它们是两个不同的对象,尽管具有相同的参数,因此它们将具有不同的哈希码。对于您的具体情况来说,这可能是问题,也可能不是问题。

如果它不只是使用 hasmap 而不关心这些细节,如果是的话,您将需要提供更好的方法来计算类的哈希码和相等性Expression

您可以以递归方式(通过计算子级哈希码的结果来计算哈希码)或以简单的方式(可能通过表示计算哈希码toString())来完成此操作。

最后,如果您打算仅使用简单类型作为键(如您所说的整数或字符串),请不要担心,没有什么区别。在这两种情况下,两个不同的项目将具有相同的哈希码。一些例子:

assert(new String("hello").hashCode() == new String("hello").hashCode());
int x = 123;
assert(new Integer(x).hashCode() == new Integer(123).hashCode());
Run Code Online (Sandbox Code Playgroud)

请注意,字符串的示例一般来说并不正确,就像我之前向您解释的那样,这只是因为字符串的 hashcode 方法根据字符串本身的内容计算值。