我只是想知道为什么在类的hashCode()
方法中使用质数?例如,当使用Eclipse
生成我的hashCode()
方法时,总是使用素数31:
public int hashCode() {
final int prime = 31;
//...
}
因为您想要乘以的数量以及要插入的存储桶的数量具有正交素数分解。
假设要插入8个桶。如果您要用来乘以的数字是8的倍数,则插入的存储桶将仅由最低有效项(一个根本没有相乘)确定。类似的条目将发生冲突。不适用于哈希函数。
31是一个足够大的素数,因此不可能被它整除(实际上,现代的Java HashMap实现将存储桶的数量保持为2的幂)。
问题内容: 在Java中,obj.hashCode()返回一些值。该哈希码在编程中有什么用? 问题答案: 用于铲装在Hash实现喜欢等。 从中接收的值用作存储集合/映射元素的存储桶编号。该存储桶编号是集合/映射中元素的地址。 完成后,它将获取元素的哈希码,然后查找哈希码指向的存储桶。如果在同一存储桶中找到了多个元素(多个对象可以具有相同的哈希码),则它将使用该方法来评估这些对象是否相等,然后确定是
哈希函数是非常有用和多功能的。通常,它们用于将一个空间映射到一个小得多的空间。当然,这意味着两个对象可能哈希到相同的值(碰撞),但这是因为您正在减少空间(鸽子原则)。函数的效率很大程度上取决于散列空间的大小。 我不是问我们为什么要用素数。很明显,如果我们用乘法,我们应该用素数。然而,乘以任何数,即使是素数,也应该比异或次优。这就是为什么所有其他非加密散列函数--以及大多数加密函数--使用异或而不是
问题内容: 决定将这些方法包含在java.lang.Object中的背后原因是什么?平等和哈希对于许多类没有意义。 建立两个接口将更加合乎逻辑: 例如,HashSet定义可能看起来像 这将防止出现一个常见的初学者错误-使用项目集而不实现equals / hashCode。 问题答案: 当我们实现一个接口时,我们注入(或接受)该接口定义的合同。 &是两个不同的合同。但是,如果我们仔细观察,就会发现它
问题内容: 在过去的几个小时中,我一直在阅读有关哈希码函数的信息,并且积累了一些有关在自定义哈希码实现中将质数用作乘数的问题。如果能就以下问题获得一些见解,将不胜感激: 在对@mattb答案的评论中,@ hstoerr提倡使用较大的质数(例如524287)而不是公共质数31。我的问题是,考虑到以下对对或元素的哈希码函数的实现: 如果数量很大,这是否会导致返回的溢出? 假设溢出不是问题(JVM执行自
问题内容: 如果我重写一个类两种方法,它必须确保,如果那么也必须是真实的。 有人可以告诉我一个简单的示例,如果违反了该示例,将会引起问题吗?我认为这与您使用该类作为Hashmap的键类型有关吗? 问题答案: 当然: 与: 从技术上讲应该是正确的,因为在两种情况下m == 3。 通常,HashMap的工作方式如下:它具有可变数量的通常称为“存储桶”的数量。存储桶的数量可以随时间变化(随着条目的添加和
或者“为什么Sun/Oracle的家伙每次都强迫我们重写equals()和hashCode()?” 每个人都知道,如果你覆盖一个对象的equals()或hashCode(),你也必须覆盖另一个,因为这两者之间有一个约定: 请注意,每当重写hashCode方法[e.equals()]时,通常有必要重写该方法,以维护hashCode方法的一般约定,即相等的对象必须具有相等的哈希代码。-对象的API文档