有人可以告诉我IdentityHashMap
的重要用例是什么吗?
答案 0 :(得分:33)
每当您希望不通过equals
而不是==
比较您的密钥时,您将使用IdentityHashMap。如果您正在进行大量的参考处理,这可能非常有用,但它仅限于非常特殊的情况。
答案 1 :(得分:30)
这门课程的典型用途是 拓扑保留对象图 转换,例如序列化 或深度复制。执行这样的 转型,一个程序必须 维护一个保持的“节点表” 跟踪所有对象引用 已经处理过的。该 节点表不能等同于不同 对象,即使它们恰好是 等于。另一个典型用途 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
用作通用地图 如果,您可以确保您用作键的对象与相等并且只有他们的参考是相同的。
获得什么收益?显然它会更快并且比使用HashMap
或TreeMap
等实现使用更少的内存。
实际上,有很多案例。例如:
Enum
秒。虽然对于枚举,甚至有更好的选择:EnumMap
Class
个对象。它们也可供参考。String
s。通过将它们指定为文字或在其上调用String.intern()
。Integer.valueOf(int)
的javadoc:
此方法将始终缓存-128到127范围内的值,包括...
演示最后一点:
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)
一个重要的案例是你在处理引用类型(而不是值),你真的想要正确的结果。恶意对象可以覆盖hashCode
和equals
方法,以应对各种恶作剧。不幸的是,它并没有经常使用。如果您要处理的界面类型未覆盖hashCode
和equals
,则通常应选择IdentityHashMap
。