一些主要的JVM类(例如String或List实现)通过返回与方法相关的? 31^n * field_n.hashCode()每个类field_n来实现equals equals.此外,Joshua Bloch在Effective Java(第9项)中推荐了这种方法.
但是,其他类(如Map.Entry实现)遵循不同的规则.例如,Map.Entry文档指出a的哈希码Map.Entry应该是
(e.getKey()==null ? 0 : e.getKey().hashCode()) ^
(e.getValue()==null ? 0 : e.getValue().hashCode())
Run Code Online (Sandbox Code Playgroud)
这有时在哈希表中使用是不切实际的,因为:
为什么Java选择Map.EntryhashCode的实现规范而不是,例如,31 * (e.getKey()==null ? 0 : e.getKey().hashCode()) + (e.getValue()==null ? 0 : e.getValue().hashCode())?
编辑1:
为了帮助解决问题,下面是一个有用代码的示例,如果许多条目具有相同的键和值,则由于散列冲突导致结果的性能非常差.
此方法计算不同地图条目的频率(使用Guava的Multiset).
public static <K, V> Multiset<Map.Entry<K, V>> computeEntryCounts(
Iterable<Map<K, V>> maps) {
ImmutableMultiset.Builder<Map.Entry<K, V>> result = ImmutableMultiset.builder();
for (Map<K, V> map : maps) {
for (Map.Entry<K, V> entry : map.entrySet()) {
result.add(entry);
}
}
return result.build();
}
Run Code Online (Sandbox Code Playgroud)
我怀疑这是否有充分的理由——我认为这只是一个疏忽——但这并不是一个严重的问题。HashSet<Map.Entry<T,T>>仅当您有 a或 a时才会出现HashMap<Map.Entry<T,T>,V>,但这种情况并不常见。(编辑添加:或者,正如 Joachim Sauer 在下面指出的那样,aHashSet<Map<T,T>>或 a HashMap<Map<T,T>,V>— 也不常见。)
请注意,不HashMap<K,V>使用,因为它仅通过键查找条目,所以它只使用。Map.Entry<K,V>.hashCode()K.hashCode()