Java语言中的散列函数

Java语言中的散列函数,java,oop,hash,function,Java,Oop,Hash,Function,我知道Java对HashMaps或Hashtable有很好的内置支持 有人知道Java语言使用什么样的哈希函数或技术吗 为了提高性能和减少访问时间,是否可以调整这些函数,使其更具体地针对某个应用程序 非常感谢您的阅读 发疯吧 此外,您始终可以将调整大小阈值和初始内存使用设置为所需的大小,这将在贴图几乎满时减少放置时间。如果您的映射是线程化的,那么使用ConcurrentHashmap也将获得巨大的性能提升。Java允许您覆盖类的hashCode()方法,以使用一种不仅非常适合您的应用程序,而且

我知道Java对HashMaps或Hashtable有很好的内置支持

有人知道Java语言使用什么样的哈希函数或技术吗

为了提高性能和减少访问时间,是否可以调整这些函数,使其更具体地针对某个应用程序

非常感谢您的阅读

发疯吧


此外,您始终可以将调整大小阈值和初始内存使用设置为所需的大小,这将在贴图几乎满时减少放置时间。如果您的映射是线程化的,那么使用ConcurrentHashmap也将获得巨大的性能提升。

Java允许您覆盖类的
hashCode()
方法,以使用一种不仅非常适合您的应用程序,而且适合您个人类型的哈希算法:

public class Employee {

   private int id;
   // Default implementation might want to use "name" for as part of hashCode
   private String name; 

   @Override
   public int hashCode() {
     // We know that ID is always unique, so don't use name in calculating 
     // the hash code.
     return id;
   }
}

哈希代码是根据存储在集合中的每个对象计算的。它是使用标准算法(根据有效的Java)计算的。更多细节请参见

您确实可以基于每个对象重写hashcode方法。实现hashcode方法的最佳方法是通过HashcodeBuilder(whcih是Commons Lang框架的一部分,请参见此处:

有关哈希代码的更多详细信息,请参阅本文:

希望有帮助

我知道Java对HashMaps或Hashtable有很好的内置支持

完全缺乏哈希映射文本的语法,我不会真的这么说

无论如何,正如其他人所指出的,由各个类指定它们的hashCode()应该是什么(默认值是内存地址的散列)。如果您实现了自己的,请确保遵循hashCode()方法的约定(特别是它需要与equals()保持一致),否则该类将不适用于HashMap中的键

您还可以直接查看j和friends的源代码,了解它们是如何实现的


为了进一步阅读,您可能想看看ConcurrentHashMap,它可以由多个线程同时安全地访问,以及TreeMap,它提供了一种为可以排序(不一定是散列)的键构建映射的方法.

一般来说,不值得过分担心标准JDK类的哈希函数。即使您可以重写字符串(您不能),在实践中,它的哈希函数实际上总是“足够好”。可能有一些例外情况——例如,某些类(如BigInteger和collections)每次都通过循环遍历它们包含的每个元素来计算其哈希代码,这在某些情况下是非常虚假的——但您多久键入一次这些类的实例

要为自己的类设计哈希代码,您要做的是将哈希代码“随机”分布在整数范围内。要做到这一点,您通常希望“混合”对象中连续字段的位(您可能对我网站上的一篇文章感兴趣,该文以图形方式说明)。将当前哈希值乘以奇数(通常为素数),然后将下一个元素的哈希值相加,通常与第一次尝试一样有效。(然而,这种方法可能会出现问题,例如,当组合的数字/哈希代码的低位往往有零时——通常没有实用的哈希函数绝对保证在所有情况下都能正常工作。)

然后,您可以考虑测试哈希代码。生成一系列随机对象(或者甚至使用一些真实对象)。,计算它们的散列码,然后从散列码的底部(例如,16位)开始计算,然后查看得到的冲突数。检查得到的冲突数是否大致与冲突数匹配。例如,如果从散列码的底部16位开始计算,则(&0xffff)然后在1000个随机对象之后,你会期望大约8次碰撞。在2000年之后,你会期望大约30次碰撞


就性能而言,在某种程度上,我认为现在获得一个分布良好的哈希代码通常比牺牲哈希质量来提高哈希计算速度更为有益。

如果您知道需要快速哈希,我建议您使用另一种实现:试试fast util()或trove()。它们显然更快,但类型特定。

请注意,如果要重写hashCode,还应该重写equals。

有一个“hashCode/equals契约”,您应该遵守该契约,即根据equals()方法彼此相等的对象必须提供相同的hashCode()值。 但是,不要求具有相同哈希代码的所有对象也相等。您应该看看哪些对象告诉您详细信息

一开始你可能很难理解其中涉及的对称性,但这绝对值得理解,除非当你将对象放入HashMap和不遵守该契约的朋友中时,你渴望在应用程序中有奇怪的行为


我还建议您获取有效Java的副本,并阅读hashCode/equals上的章节以完全理解它。

我相信您忘记了equal。可能还想在其中添加@Override。Added.Ah-在浏览器文本框中而不是IDE中编写Java代码的奇妙之处:)我不认为这个答案是正确的。hashCode()返回的整数是Hashtble的实数键,然后Hashtable使用哈希函数对hashCode()进行哈希。这个答案意味着Java给了您一个机会给Hashtable一个哈希函数,但不,这是错误的。hashCode()给出的是实数键,而不是散列函数。@Jackson,它似乎类似于CLRS,hashCode实际上是一种散列函数!如果你看它,它说两个不同的对象