【发布时间】:2011-04-23 07:05:01
【问题描述】:
如何测试/分析 Java 中的 hashCode() 实现?即它是否合理均匀地分配我的测试数据等? java API本身有没有简单粗暴的方法?
【问题讨论】:
标签: java collections hashmap
如何测试/分析 Java 中的 hashCode() 实现?即它是否合理均匀地分配我的测试数据等? java API本身有没有简单粗暴的方法?
【问题讨论】:
标签: java collections hashmap
Map<Integer, Integer> hashCodes = new HashMap<Integer, Integer>();
for (YourHashcodedClass testData: largeCollectionOfTestData) {
Integer hashCode = Integer.valueOf(testData.hashCode());
Integer occurrences = hashCodes.get(hashCode);
if (occurrences == null) {
occurrences = 0;
}
hashCodes.put(hashCode, occurrences+1);
}
然后分析您的地图是否有碰撞。
【讨论】:
老实说,如果您遵循最佳做法,则不必分析或测试您的 hashCode() 方法的分布。请参阅下面来自Effective Java 的哈希码配方。此外,即使您写得不好,HashMap 实现也会重新散列您的结果以减少冲突:
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
您也可以使用Apache Commons Lang 中的HashCodeBuilder 为您构建哈希码。
result 的int 变量中存储一些恒定的非零值,例如17。int 哈希码c:
boolean,则计算(f ? 1 : 0)
byte, char, short, int,则计算(int) f
long,则计算(int) (f ^ (f >>> 32))
float,则计算Float.floatToIntBits(f)
double,计算Double.doubleToLongBits(f),然后像上面一样散列结果long。equals 方法通过递归调用equals 来比较该字段,则在该字段上递归调用hashCode。如果该字段的值为null,则返回0。Arrays.hashCode 方法之一。c组合成result如下:result = 31 * result + c;
【讨论】: