Java库提供完美的散列?

时间:2015-04-20 15:47:35

标签: java algorithm data-structures hash

我已经做了一些搜索,发现了一些关于在Java中支持完美(即没有冲突)哈希的有用帖子。

Why doesn't Java's hashCode support universal hashing?

Is it possible in java make something like Comparator but for implementing custom equals() and hashCode()

但我正在寻找一个实用的解决方案,希望以测试库的形式。我有一个适合完美散列的情况:基本上,我们可以假设密钥集是固定的,程序运行很长时间并进行大量查找。 (这不完全正确,但是密钥添加得很少,以至于它足够近似,如果我必须定期重新哈希或者处理那些事情,那就没问题。)

基本上,我希望能够增加负载系数并减少碰撞。换句话说,目标是减少内存使用,并增加吞吐量(即每秒的查找次数)。

有一些问题。显然,存在的问题是如果hashCode()没有返回不同的值,那么完美的散列是不可能的。除了散列算法之外还有其他一些注意事项,比如hashCode()的复杂性(或者我是否应该在关键对象上缓存哈希码等)或者我用来最初将对象映射到整数或长整数的其他函数。

我想象的是能够在后台线程中重新哈希,尝试不同的哈希函数来找到一个完美的哈希函数或者至少是一个好的哈希函数。我虽然对另一个解决方案持开放态度。我想使用经过测试的代码而不是自己编写代码,尽管我也对此持开放态度。

3 个答案:

答案 0 :(得分:2)

如果您的数据足够随机,则不需要完美哈希。 Mitzenmacher有一篇很好的文章解释了为什么在实践中完美的哈希很难以及为什么它(通常)在实践中是不必要的。我会在标题中为您提供一个链接并粘贴,以便在链接消失时找到它。

http://people.seas.harvard.edu/~salil/research/streamhash-Jun10.pdf

为什么简单哈希函数有效: 利用数据流中的熵

Michael Mitzenmacher Salil Vadhan 工程学院&应用科学

2010年6月23日

散列是许多在实践中广泛使用的算法和数据结构的基础。对于散列的理论分析,有两种主要方法。首先,可以假设散列函数是真正随机的,将每个数据项独立且均匀地映射到该范围。这种理想化的模型是不现实的,因为真正的随机散列函数需要指数位来描述。或者,当使用显式的散列函数族时,可以提供严格的性能界限,例如2-universal或O(1)-ly独立族。对于这些家庭来说,性能保证通常明显弱于理想的散列。

然而,在实践中,通常观察到简单的散列函数(包括2通用散列函数)如通过对真正随机散列函数的理想化分析所预测的那样执行。在本文中,我们试图解释这种现象。我们证明了通用散列函数在实践中的强大性能可以自然地从散列函数的随机性和数据的组合中产生。具体而言,在关于随机源和随机性提取的大量文献之后,我们将数据建模为来自“块源”,其中每个新数据项具有一些给定先前的“熵”。只要每个数据项的(Renyi)熵足够大,就会发现从2通用族中选择哈希函数时的性能与真正的随机哈希函数基本相同。我们描述了几个示例应用程序的结果,包括线性探测,平衡分配和布隆过滤器。

答案 1 :(得分:0)

我不明白你为什么要在后台线程中重新哈希。什么能保证新的哈希表有较小的冲突?也许如果你搜索collosion并重新哈希那些具有其他哈希函数。但是,如果一些新的哈希码仍在表中呢?重新哈希,直到冲突数为零?什么都不能保证你不会有爆炸。请参阅bithday问题以获取证据:http://en.wikipedia.org/wiki/Birthday_problem

我认为你需要一个具有良好抗冲突性的良好哈希函数。 我和你分享我的研究成果。我希望它有所帮助!

我发现的最佳防碰撞哈希函数是 carc32 。使用此函数,N对象中的任何一个之间的碰撞概率为(N - 1) / 2^32Here第二篇文章会告诉你原因。 There是另一项加强研究的研究。 Java中有一个内置类:CRC32

答案 2 :(得分:-2)

使用像BouncyCastle这样的加密库来提供更好的散列函数。请参阅Hash String via SHA-256 in Java

另一种选择似乎是http://www.anarres.org/projects/jperf/,但我自己没有尝试过。