5

我正在开发一个基于散列的程序。我的问题是 String 的 HashCode 是否会在整个应用程序中保持不变。

我之所以问这个问题,是因为 Mecached Servers 中的 KetamaMemcachedSessionLocator 以这种方式工作 如果有两台服务器运行 Memcache,我想从特定服务器中定位一个密钥。

String key = "MyString";
int keyid = key.hashCode();
int v = keyid % 1;  //( I assume that this will contact the First Server to retrieve that value )
int v = keyid % 2;  //( I assume that this will contact the Second Server to retrieve that value )
String value = MemcachedClient.get(key, v);

后续以本网站为基础实施上述

http://dev.mysql.com/doc/refman/5.0/en/ha-memcached-using-hashtypes.html

请分享您的观点,如果您发现任何问题,如果上述方式有效。

4

2 回答 2

10

根据哈希码合约,如果string1.eqauls(string2)

The java.lang.String hash function

为了提供快速实现,Java String 类的早期版本提供了一个 hashCode() 实现,它考虑从字符串中选择最多 16 个字符。对于一些常见的数据,这工作得非常糟糕,提供了令人无法接受的集群结果,从而降低了哈希表的性能。

从 Java 1.2 开始,java.lang.String 类在整个字符串文本上使用乘积和算法实现其 hashCode()。例如,给定一个 java.lang.String 类的实例 s,其哈希码 h(s) 定义为

h(s)=\sum_{i=0}^{n-1}s[i] \cdot 31^{n-1-i}

其中术语使用 Java 32 位 int 加法求和,s[i] 表示字符串的第 i 个字符,n 是 s 的长度。

与任何一般的散列函数一样,冲突是可能的。例如,字符串“FB”和“Ea”具有相同的哈希值。String 的 hashCode() 实现使用素数 31,'a' 和 'B' 的差值只有 31,所以计算为 70 × 31 + 66 = 69 × 31 + 97。

检查Collections Framework Enhancements in Java SE 7您是否看到其中有变化,谁知道会发生变化。

替代散列函数仅适用于字符串类型的键。

于 2012-10-28T07:02:01.553 回答
1

是和不是。

hashCode()合约规定两个相等的字符串在同一个 JVM 中具有相同的哈希码。这意味着只要字符串不改变,代码就不会改变。

另一方面,实际hashCode()实现已从一个 JVM 版本更改为另一个版本和/或从一个 JVM 供应商更改为另一个。例如,Oracle Java 7u6 为超过一定大小的字符串提供了更快的替代散列函数。目前它只在 Collections 框架中使用,但它很可能成为 Java 8 的系统范围的默认设置。

基本上,您可以依赖hashCode()于在同一个应用程序中保持一致,但不能在不同的应用程序实例之间保持一致。如果您打算存储或共享哈希码,您可能应该实现自己的函数。

另一个潜在的兴趣点是,hashCode()Java 中定义的长度为int32 位。这绝不是一个唯一的标识符——冲突非常频繁,程序员应该处理它们。如果您的存储系统依赖于唯一键,您可能希望使用更强的散列函数,例如SHA-2,无论如何。

于 2012-10-28T07:17:57.803 回答