【发布时间】:2013-12-21 14:35:03
【问题描述】:
我将大量对象(对象的字节数组中存储的值的唯一组合)存储在哈希映射(约 280 万个对象)中,并且在检查我是否有哈希码冲突时(32 -bit hash),我很惊讶地发现没有,而在统计上,我有几乎 100% 的机会发生至少一次碰撞(参见http://preshing.com/20110504/hash-collision-probabilities/)。
因此,我想知道我检测碰撞的方法是否有问题,或者我是否非常幸运......
这是我尝试从地图中存储的 280 万个值中检测碰撞的方法:
HashMap<ShowdownFreqKeysVO, Double> values;
(...fill with 2.8 mlns unique values...)
HashSet<Integer> hashes = new HashSet<>();
for (ShowdownFreqKeysVO key:values.keySet()){
if (hashes.contains(key.hashCode())) throw new RuntimeException("Duplicate hash for:"+key);
hashes.add(key.hashCode());
}
这是对象创建哈希值的方法:
public class ShowdownFreqKeysVO {
//Values for the different parameters
public byte[] values = new byte[12];
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode(values);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ShowdownFreqKeysVO other = (ShowdownFreqKeysVO) obj;
if (!Arrays.equals(values, other.values))
return false;
return true;
}
}
任何关于我做错了什么的想法/提示将不胜感激!
谢谢, 托马斯
【问题讨论】:
-
hashes在这行HashSet<Integer> hashes = new HashSet<>();之后包含什么?您如何填充hashes的值? -
他在循环中添加了
hashes.add(key.hashCode());。 -
@mprivat 这只是实现 hashCode 的常见样板。
-
这对我来说是正确的。检查该集合是否包含 280 万个元素:
(...fill with 2.8 mlns unique values...)中可能有问题。或者你很幸运。我也会简单地使用return Arrays.hashCode(values):在这个 hashCode 中添加 31 是不必要的。 -
@LeosLiterak:您应该阅读有关生日悖论的内容 (en.wikipedia.org/wiki/Birthday_problem)。在只有 23 人的人口中,有 50% 的概率有两个人在一年中的同一天出生(尽管 23 比 365 少得多)。而且我们这里说的不是 2^(12*8),而是 2^32(可能的 int hashCodes 的数量)
标签: java hash hashcode hash-collision