[英]Use cases for IdentityHashMap
谁能告诉IdentityHashMap
的重要用例是什么?
Whenever you want your keys not to be compared by equals
but by ==
you would use an IdentityHashMap.每当您希望您的键不被equals
而是通过==
进行比较时,您将使用 IdentityHashMap。 This can be very useful if you're doing a lot of reference-handling but it's limited to very special cases only.如果您进行大量引用处理,这可能非常有用,但仅限于非常特殊的情况。
The documentations says: 文件说:
A typical use of this class is topology-preserving object graph transformations, such as serialization or deep-copying.此类的典型用途是保留拓扑的对象图转换,例如序列化或深度复制。 To perform such a transformation, a program must maintain a "node table" that keeps track of all the object references that have already been processed.为了执行这样的转换,程序必须维护一个“节点表”来跟踪所有已经处理过的对象引用。 The node table must not equate distinct objects even if they happen to be equal.节点表不能等同于不同的对象,即使它们碰巧相等。 Another typical use of this class is to maintain proxy objects.此类的另一个典型用途是维护代理对象。 For example, a debugging facility might wish to maintain a proxy object for each object in the program being debugged.例如,调试工具可能希望为被调试程序中的每个对象维护一个代理对象。
One case where you can use IdentityHashMap is if your keys are Class objects.您可以使用 IdentityHashMap 的一种情况是您的键是 Class 对象。 This is about 33% faster than HashMap for gets!这比获取 HashMap 快约 33%! It probably uses less memory too.它也可能使用更少的内存。
You can also use the IdentityHashMap
as a general purpose map if you can make sure the objects you use as keys will be equal if and only if their references are equal.如果您可以确保用作键的对象相等,当且仅当它们的引用相等时,您也可以将IdentityHashMap
用作通用映射。
To what gain?有什么收获? Obviously it will be faster and will use less memory than using implementations like HashMap
or TreeMap
.显然,与使用HashMap
或TreeMap
等实现相比,它会更快并且使用更少的内存。
Actually, there are quite a lot of cases when this stands.实际上,这种情况出现的情况相当多。 For example:例如:
Enum
s. Enum
Although for enums there is even a better alternative:EnumMap
尽管对于枚举,还有更好的选择:EnumMap
Class
objects. Class
对象。 They are also comparable by reference.它们也可以通过引用进行比较。String
s.实习String
s。 Either by specifying them as literals or calling String.intern()
on them.通过将它们指定为文字或对它们调用String.intern()
。Integer.valueOf(int)
:例如从Integer.valueOf(int)
的 javadoc 引用:
This method will always cache values in the range -128 to 127, inclusive...此方法将始终缓存 -128 到 127 范围内的值,包括...
To demonstrate the last point:为了证明最后一点:
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));
Output will be, as expected (because we used the same Object
references to query values from the map):输出将如预期的那样(因为我们使用相同的Object
引用来查询地图中的值):
strkey: Key #0
java.lang.Object@1c29bfd: Key #1
1234567: Key #2
HashMap creates Entry objects every time you add an object, which can put a lot of stress on the GC when you've got lots of objects. HashMap 每次添加对象时都会创建 Entry 对象,当你有很多对象时,这会给 GC 带来很大的压力。 In a HashMap with 1,000 objects or more, you'll end up using a good portion of your CPU just having the GC clean up entries (in situations like pathfinding or other one-shot collections that are created and then cleaned up).在具有 1,000 个或更多对象的 HashMap 中,您最终将使用 CPU 的很大一部分,只是让 GC 清理条目(在诸如寻路或其他创建然后清理的一次性集合的情况下)。 IdentityHashMap doesn't have this problem, so will end up being significantly faster. IdentityHashMap 没有这个问题,所以最终会明显更快。
See a benchmark here: http://www.javagaming.org/index.php/topic,21395.0/topicseen.html在此处查看基准: http : //www.javagaming.org/index.php/topic,21395.0/topicseen.html
This is a practical experience from me:这是我的实践经验:
IdentityHashMap leaves a much smaller memory footprint compared to HashMap for large cardinalities.对于大基数,与 HashMap 相比,IdentityHashMap 留下的内存占用要小得多。
One important case is where you are dealing with reference types (as opposed to values) and you really want the correct result.一个重要的情况是您正在处理引用类型(而不是值)并且您确实想要正确的结果。 Malicious objects can have overridden hashCode
and equals
methods getting up to all sorts of mischief.恶意对象可能会覆盖hashCode
和equals
方法,从而引发各种恶作剧。 Unfortunately, it's not used as often as it should be.不幸的是,它没有像应有的那样经常使用。 If the interface types you are dealing with don't override hashCode
and equals
, you should typically go for IdentityHashMap
.如果您处理的接口类型不覆盖hashCode
和equals
,您通常应该选择IdentityHashMap
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.