IdentityHashMap的用例

时间:2009-05-08 06:51:39

标签: java

有人可以告诉我IdentityHashMap的重要用例是什么吗?

7 个答案:

答案 0 :(得分:33)

每当您希望不通过equals而不是==比较您的密钥时,您将使用IdentityHashMap。如果您正在进行大量的参考处理,这可能非常有用,但它仅限于非常特殊的情况。

答案 1 :(得分:30)

documentations说:

  

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

答案 2 :(得分:21)

如果您的密钥是Class对象,则可以使用IdentityHashMap的一种情况。获得的速度比HashMap快33%!它也可能使用更少的内存。

答案 3 :(得分:16)

每次添加对象时,HashMap都会创建Entry对象,当你有很多对象时,这会给GC带来很大的压力。在具有1,000个或更多对象的HashMap中,您最终将使用大部分CPU来清理GC(在路径查找或其他一次性集合中创建然后清理)。 IdentityHashMap没有这个问题,因此最终会更快。

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

答案 4 :(得分:16)

您还可以将IdentityHashMap用作通用地图 如果,您可以确保您用作键的对象与相等并且只有他们的参考是相同的。

获得什么收益?显然它会更快并且比使用HashMapTreeMap等实现使用更少的内存。


实际上,有很多案例。例如:

  • Enum秒。虽然对于枚举,甚至有更好的选择:EnumMap
  • Class个对象。它们也可供参考。
  • Interned String s。通过将它们指定为文字或在其上调用String.intern()
  • 缓存的实例。有些类提供其实例的缓存。例如,引用Integer.valueOf(int)的javadoc:

      

    此方法将始终缓存-128到127范围内的值,包括...

  •   
  • 某些库/框架将只管理一个ceratin类型的实例,例如Spring beans。
  •   
  • 单身人士类型。如果使用使用 Singleton 模式构建的类型的istances,您还可以确保(最多)存在一个实例,因此引用相等性测试将有资格进行相等性测试。
  •   
  • 您明确处理的任何其他类型,仅使用相同的引用来访问用于将值放入地图的值。
  •   

     

演示最后一点:

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

答案 5 :(得分:12)

这是我的实践经验:

与HashMap相比,IdentityHashMap留下了更小的内存占用空间。

答案 6 :(得分:3)

一个重要的案例是你在处理引用类型(而不是值),你真的想要正确的结果。恶意对象可以覆盖hashCodeequals方法,以应对各种恶作剧。不幸的是,它并没有经常使用。如果您要处理的界面类型未覆盖hashCodeequals,则通常应选择IdentityHashMap