对于表示时间戳的Long键,使用IdentityHashMap(在Java中)是否安全?

时间:2015-10-09 20:45:22

标签: java hashmap

在我的Java程序中,我有一个List< Long>时间戳以毫秒为单位的时间。每次关联一些值(例如Map< Long,Float>)。现在我正在使用HashMap,但通过分析我注意到putAll具有最高的自我时间百分比。所以为了优化这个,我想知道我是否可以使用IdentityHashMap,但这样安全吗?结果发生了变化,似乎没有,但为什么呢?

我这样做是为了检查,但是等于'保持虚假。有人可以解释一下吗?

boolean equal = false;
for (int i = 0; i < times.size(); i++) {
    for (int j = i + 1; j < times.size(); j++) {
        if (times.get(i) == times.get(j)) {
            equal = true;
            break;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

  

是[使用IdentityHashMap代替HashMap]安全吗?

不,如果密钥覆盖Object.equals()和/或Object.hashCode(),则不会。

  

结果发生了变化,似乎没有,但为什么呢?

IdentityHashMapHashMap之间的区别在于前者使用System.identityHashCode()==运算符进行哈希和比较键,而HashMap使用键出于这些目的,我们拥有hashCode()equals()种方法。如果键覆盖Object.equals(),那么您可以使用两个键

k1.equals(k2) && (k1 != k2)

true。此类密钥与IdentityHashMap不同,但相当于HashMap。这样的对很容易获得;例如:

Long k1 = new Long(1);
Long k2 = new Long(1);

会做的。

IdentityHashMap是针对特殊情况,您希望每个不同的对象都是一个独特的键,尽管对象对它们自己的等效性有所了解。如果您不确定是否需要它,那么您不需要它。如果HashMap适当地满足您的目的,那么您不需要也可能不需要IdentityHashMap

javadocs这样说:

  

此类不是通用的Map实现!虽然这个类实现了Map接口,但它故意违反了Map的一般契约,它要求在比较对象时使用equals方法。此类仅适用于需要引用相等语义的极少数情况。

(强调原文)