Java HashMap或IdentityHashMap

Fel*_*lix 8 java

在某些情况下,map中使用的键对象不会覆盖Object中的hashCode()和equals(),例如,使用套接字连接或java.lang.Class作为键.

  1. 将这些对象用作HashMap中的键是否存在任何潜在的缺陷?
  2. 在这些情况下我应该使用IdentityHashMap吗?

RMo*_*sey 5

如果equals()hashCode()未在关键对象上重写,则HashMap和IdentityHashMap应具有相同的语义.默认的equals()实现使用引用语义,默认值hashCode()是对象的系统标识哈希码.

这只有在对象的不同实例被视为逻辑上相等的情况下才有害.例如,如果您的密钥是:您不希望使用IdentityHashMap:

new Integer(1)
Run Code Online (Sandbox Code Playgroud)

new Integer(1)
Run Code Online (Sandbox Code Playgroud)

因为这些是技术上不同的Integer类实例.(你应该真的在使用Integer.valueOf(1),但那是偏离主题的.)

Class因为键应该没问题,除非在非常特殊的情况下(例如,hibernate ORM库在运行时生成类的子类以实现代理.)作为开发人员,我会怀疑将Connection对象存储在Map中的代码密钥(如果您正在管理数据库连接,可能应该使用连接池?).它们是否可以工作取决于实现(因为Connection只是一个接口).

此外,重要的是要注意HashMap期望equals()hashCode()决心保持不变.特别是,如果您实现了一些hashCode()在密钥对象上使用可变字段的自定义,则更改密钥字段可能会使密钥在HashMap的错误哈希表桶中"丢失".在这些情况下,您可以使用IdentityHashMap(取决于对象和您的特定用例),或者您可能只需要不同的equals()/hashCode()实现.