本哈希码值的Java串的计算方法为:(String.哈希码()):

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

是否有任何情况下(说JVM版本,供应商,等等。) 以下表达将评估,假的?

boolean expression = "This is a Java string".hashCode() == 586653468

更新#1: 如果你说答案是"是的,有这样的情况下"-然后请给一个具体的例子的时候",这是一个Java string"。哈希码()!= 586653468.尽可能具体/具体作为可能。

更新#2: 我们都知道,依靠执行情况的详细信息的哈希码()是糟糕的一般。但是,我要讲的串。哈希码()-所以请继续答复专注于字符串。哈希码().对象。哈希码()是完全不相干的上下文中的这个问题。

有帮助吗?

解决方案

我可以看到这一文件早Java1.2.

虽然这是真的, 在一般 你不应该依靠一个列码的执行剩下的同样,它现在有记录的行为 java.lang.String, ,因此改变其会计数为打破现有的合同。

只要有可能,你不应该依赖哈希码留相同的版本,等等-但在我心中 java.lang.String 是一个特殊的情况下,只是因为算法 被指定...所以,只要你愿意放弃兼容的版本之前,算法是指定的,当然。

其他提示

我发现一些有关JAVA1.0和1.1和>=1.2:

在JAVA为1.0。x和1.1.x的哈希码 功能用于长串的工作 取样的每个nth符。此 漂亮好的保证你会 许多串的散列相同的 值,因此减慢Hashtable 查找。在JAVA1.2的功能 经改进的繁殖的结果 迄今为止31然后添加下一个 字符序列。这是一个 慢点,但是很好 避免碰撞。资料来源: http://mindprod.com/jgloss/hashcode.html

不同的东西,因为你似乎需要一个数字:关于如何使用CRC32或MD5而不是哈希码,你是好去-没有讨论,并无后顾之忧,在所有的...

你不应该依靠一个列码等于一个特定的价值。只是它将会返回一致的结果在同一执行。API docs说下面的:

一般合同哈希码是:

  • 每当它援引上相同的对象多次在执行Java申请,哈希码方法必须始终如一地返回相同的整数,没有提供任何信息的使用等于比较对象被修改。这整数不需要保持一致,从一个执行应用到另一个执行相同的应用程序。

编辑 因为如果是的话,为什么不试用一串。哈希码()指定一串的散列的代码计算,任何违反这将违反公共API规范。

如上所述,一般不应依赖列码的一类剩余的相同。请注意,即使随后运行的 相同的应用程序同VM 可能会产生不同的散列值。据我所知太阳JVM的散列函数计算的相同的散列在每次运行,但这不能保证。

注意,这不是理论上的。散列函数为java。郎。字符串 是改变 在JDK1.2(旧的散列有问题的层次串喜欢的网址或文件的名字,因为它往往产生相同的散列为串其中只有不同,在结束)。

java。郎。串是一个特殊的情况下,作为算法的其哈希码()是(现在)的记录,所以你可能可以依赖的。我仍然认为它不好的做法。如果你需要一散列算法的特殊、有记录的性质,只是写一个:-).

另一个(!) 问题的担心是可能改变的执行情况之间的早/晚版本。我不相信的实施细节,并因此可能升级到一个 未来 Java version可能导致的问题。

底线是,我不会依赖的执行情况 hashCode().

也许你可以突出什么问题你实际上是在试图解决使用这种机制,这将突出一个更合适的办法。

如果你担心的变化可能不兼容的虚拟机,只是复制的现有哈希码的执行工作纳入自己的工具类,并使用,以产生您hashcodes.

只要回答你的问题,而不继续的任何讨论。Apache和谐JAVA执行情况似乎使用了不同算法,至少它看起来完全不同的:

太阳JAVA

public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;

        for (int i = 0; i < len; i++) {
            h = 31*h + val[off++];
        }
        hash = h;
    }
    return h;
}

Apache和谐

public int hashCode() {
    if (hashCode == 0) {
        int hash = 0, multiplier = 1;
        for (int i = offset + count - 1; i >= offset; i--) {
            hash += value[i] * multiplier;
            int shifted = multiplier << 5;
            multiplier = shifted - multiplier;
        }
        hashCode = hash;
    }
    return hashCode;
}

觉得免费的检查你自己...

本哈希码将基于计算ASCII值的字符串。

这是执行在String类如下

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        hash = h = isLatin1() ? StringLatin1.hashCode(value)
                              : StringUTF16.hashCode(value);
    }
    return h;
}

冲突在哈希码是不可避免的。例如,串"Ea"和"FB"给予同样的哈希码为2236

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top