Java 如何从散列计算数组索引

Java 如何从散列计算数组索引,java,hash,Java,Hash,我看过一些关于如何为字符串创建哈希的示例。以下是Java中的一个示例: private int getHashCode(String text) { int hash = 7; for (int i = 0; i < text.length(); i++) { hash = hash * 31 + text.charAt(i); } return hash; } private int getHashCode(字符串文本){ int ha

我看过一些关于如何为字符串创建哈希的示例。以下是Java中的一个示例:

private int getHashCode(String text) {
    int hash = 7;
    for (int i = 0; i < text.length(); i++) {
        hash = hash * 31 + text.charAt(i);
    }

    return hash;
}
private int getHashCode(字符串文本){
int hash=7;
对于(int i=0;i

这当然可以产生大量的数据。如果我将字符串存储在一个数组中,并且我只有10个数组项,那么如何从哈希代码计算数组索引?当然,我可以使用HashMap来实现这一点,但我想这样做是学习如何从哈希代码创建索引的一部分。

您可以使用余数运算符(
%
)将哈希代码映射到数组的索引:

int index = obj.getHashCode ("SomeString") % yourArray.length;
当然,您应该能够处理冲突(即两个或多个字符串映射到同一数组索引的情况)

HashMap
通过在数组的每个索引中存储一个条目实例来处理此类潜在冲突,该实例可以指向映射到该索引的下一个条目(从而形成一个链表)

编辑:

正如下面正确评论的那样,
%
运算符不适用于负哈希代码。作为替代方案,您可以使用(在Java 8中引入的):

int index = Math.floorMod (obj.getHashCode ("SomeString"), yourArray.length);
这保证返回一个非负索引,而与哈希代码的符号无关


或者,您可以采用
HashMap
实现中使用的替代方法。如果数组的长度总是2的幂,那么可以从java hashmap实现中使用
obj.getHashCode(“SomeString”)&(yourArray.length-1)

n->数组大小


index=hashCode(key)和(n-1)。

散列函数输出是一个介于0到n之间的数字,散列本身就是索引。但是,哈希对您来说应该是透明的,您不应该通过索引访问对象。如果您想要一个较短的数组,您应该收缩函数codomain,因为哈希不是索引。当文本较长时,上面的代码将生成非常大的值。散列只是获取索引的一部分。我仍然缺少从散列到索引的部分。如果你使用的是一个代码域在数组范围内的函数,你可以从散列到索引。散列函数是一个函数f:String->[A,b],在您的例子中,A=0,b=length-1。因为Java的
%
运算符是不正常的,如果您有一个负的散列码,这将不起作用。@khelwood,您可以很容易地解释这一点(例如,通过对散列码的绝对值应用
%
运算符)。值得注意的是,当更改数组的大小时,每个项应存储的位置可能会更改。@davmac这是一个有效点。因此,Eran的简单解决方案意味着,如果需要调整数组大小,则不能使用它。@AndroidDev
HashMap
使用类似的解决方案。调整数组大小时,必须重新设置所有条目的大小(即,在将它们添加到新数组之前,应重新计算它们的数组索引)。