字符串的哈希码对于整个应用程序是否相同?

时间:2012-10-28 06:59:45

标签: java

我正在开发一个基于Hashing的程序。 我的问题是,字符串的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

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

2 个答案:

答案 0 :(得分:10)

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

,它将始终相同

The java.lang.String hash function

为了提供快速实现,早期版本的Java String类提供了一个hashCode()实现,该实现最多考虑从字符串中挑选出16个字符。对于一些常见数据,这种方法效果很差,提供了不可接受的聚类结果,从而降低了哈希表的性能。

从Java 1.2开始,java.lang.String类在字符串的整个文本上使用乘积和算法实现其hashCode()。例如,给定java.lang.String类的实例,将具有由

定义的哈希码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,因为你看到它有变化,谁知道会有变化。

替代散列函数仅适用于String类型的键。

答案 1 :(得分:1)

是和否。

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

另一方面,实际的hashCode()实现已经从一个JVM版本更改为另一个JVM版本和/或从一个JVM供应商更改为另一个JVM版本。例如,对于超过特定大小的字符串,Oracle Java 7u6 provides a faster alternative hashing function。目前它仅在Collections框架中使用,但它很可能成为Java 8的系统范围默认值。

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

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