考虑这个课程:
public final class MyDate {
private int year, month, day;
public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
//Some stuff
@Override
public int hashCode() {
return ((year << 4) | month) << 5 | day;
}
}
这是一个完美的散列函数,因为在内存中我们有:
因此,红色,5 bits
存储当天(1到31),黄色4 bits
存储月份(1到12),其他存储年份(1到16777215)。
完美hashFunction
有什么好处? AFAIK,它可以保证O(1)
中HashSet
中的添加/删除/包含,但是我可以获得其他好处吗?
我看到很多哈希函数都使用素数,构造一个哈希函数的最佳方式是什么(我想创建一个完美的哈希函数是非常/罕见的)?
<小时/> 编辑:
关于素数 - &gt;已回答here
答案 0 :(得分:8)
完美的哈希函数可确保您不会发生冲突。但是,为了能够使用一个,您必须确切地知道需要进行哈希处理的键值集合,这通常不是这种情况。
其他不太完美,但仍然有良好的哈希函数(以及冲突解决机制)没有这个要求,并且计算速度非常快,所以它们通常更合适。
答案 1 :(得分:1)
根据Juampi,它很快。 多快? 大约为O(1)。 Redis是通过哈希表在内存中进行常量时间查找的一个很好的例子。
如果你没有在哈希结果上只有一个元素的桶,那么你需要使用equals来比较每个项目,这样你就可以查找O(1加z),其中z是桶大小。
但是非常慢的哈希函数肯定不是一个好主意。