用于IdentityHashMap的用例

任何人都可以告诉一下IdentityHashMap的重要用例是什么?

文件说:

这个类的一个典型用途是拓扑保持对象图转换,如序列化或深度复制。 为了执行这种转换,程序必须维护一个“节点表”,用于跟踪所有已经处理的对象引用。 节点表不能等同不同的对象,即使它们恰好相等。 这个类的另一个典型用途是维护代理对象。 例如,debugging工具可能希望为正在debugging的程序中的每个对象维护一个代理对象。

每当你想让你的密钥不能通过equals进行比较,而是通过==来进行比较的时候,你可以使用一个IdentityHashMap。 如果你做了大量的引用处理,这可能是非常有用的,但它仅限于非常特殊的情况。

你可以使用IdentityHashMap的一种情况是,如果你的键是Class对象的话。 这比HashMap快了33%! 它可能也使用较less的内存。

每次添加一个对象时,HashMap都会创build一个Entry对象,当有很多对象的时候,这会给GC带来很大的压力。 在一个包含1,000个或更多对象的HashMap中,最终只需要使用GC的一大部分清理条目(如path查找或其他一次性创build并清理的集合)。 IdentityHashMap没有这个问题,所以最终会明显更快。

在此处查看基准: http : //www.javagaming.org/index.php/topic,21395.0/topicseen.html

这是我的实践经验:

与大型基数的HashMap相比,IdentityHashMap留下更小的内存空间。

你也可以使用IdentityHashMap作为一个通用的映射, 如果你能确保你用作键的对象将是相等的当且仅当它们的引用是相等的。

为了什么收益? 显然这比使用像HashMap或者TreeMap这样的实现会更快并且使用更less的内存。


事实上,现在有很多案例。 例如:

  • Enum s。 虽然对于枚举来说,还有更好的select: EnumMap
  • Class对象。 他们也可以参考。
  • Interned String 。 通过将它们指定为文字或对其调用String.intern()
  • caching的实例。 有些类提供了对其实例的caching。 例如从Integer.valueOf(int)的javadoc引用:

此方法将始终将值caching在-128到127的范围内,包括…

  • 某些库/框架只能pipe理一种angular蛋白types的实例,例如Spring beans。
  • 单身人士types。 如果您使用以Singleton模式构build的types的istances,也可以确保(至多)一个实例存在于其中,因此引用相等性testing将有资格进行相等性testing。
  • 任何其他types的地方,您明确地只使用相同的引用来访问用于将值放入地图的值。

  • 为了certificate最后一点:

     Map<Object, String> m = new IdentityHashMap<>(); // Any keys, we keep their references Object[] keys = { "strkey", new Object(), new Integer(1234567) }; for (int i = 0; i < keys.length; i++) m.put(keys[i], "Key #" + i); // We query values from map by the same references: for (Object key : keys) System.out.println(key + ": " + m.get(key)); 

    输出将如预期的那样(因为我们使用相同的Object引用来查询地图中的值):

     strkey: Key #0 java.lang.Object@1c29bfd: Key #1 1234567: Key #2 

    一个重要的情况是你正在处理引用types(而不是值),你真的想要正确的结果。 恶意对象可以重载hashCode并且可以使用各种恶作剧。 不幸的是,它并没有经常使用。 如果您正在处理的接口types不覆盖hashCodeequals ,则通常应该使用IdentityHashMap