您可以查看源代码。(我正在查看JDK 6)HashMap.get()非常简单:
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
hash()函数进行一些额外的移位和异或操作以“改进”哈希码。
ConcurrentHashMap.get()函数稍微复杂一些,但并不是太多。
public V get(Object key) {
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, hash);
}
再次强调,hash()函数会进行一些移位和异或操作。setMentFor(int hash)函数只是简单的数组查找。唯一复杂的部分在于Segment.get()函数。但即使如此,它看起来也并不像什么高深的科学:
V get(Object key, int hash) {
if (count != 0) { // read-volatile
HashEntry<K,V> e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key)) {
V v = e.value;
if (v != null)
return v;
return readValueUnderLock(e); // recheck
}
e = e.next;
}
}
return null;
}
它卡住的唯一地方是readValueUnderLock()。注释说这在内存模型下是合法的,但从未发生过。
总体而言,两者的代码看起来非常相似。ConcurrentHashMap只是更好地组织了一下。所以我猜性能应该足够相似。
话虽如此,如果put操作确实非常少,您可以考虑实现“写时复制”类型的机制。