是否预先计算了java中的String hashCode?

时间:2013-07-10 11:36:30

标签: java hashcode

我说的时候用Java写的。

String str= "abcd";
str.hashCode(); 

我的问题是什么时候计算Hashcode? @第1行或@第2行?

我假设,哈希码是预先计算的。每当更新字符串时,哈希码也可能“更新”。

或其他方式,即每次调用str.hashCode()时,java都会使用描述为here的公式计算它。

Consistency of hashCode() on a Java string

6 个答案:

答案 0 :(得分:9)

字符串无法更新,因为它们是不可变的,并且在计算一次后缓存该值:

public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

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

答案 1 :(得分:1)

您无法“更新”字符串。字符串是不可变的。当您“更改”字符串实例时,实际上会获得一个新的字符串实例。

答案 2 :(得分:1)

您无法将现有String实例更新为String is immutable。您可以做的是创建一个新实例并将其分配给同一个变量。

答案 3 :(得分:0)

String_hashCode()方法仅在您调用时触发,就像您在Java中编写或使用的任何其他方法一样。

因此,为了回答您的问题,在创建String时不会计算哈希码。

如果你看到哈希码方法,那么它被编写为只计算一次并将预先计算的哈希码值保存到局部变量哈希

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;
} 

因此,只有在调用方法时才计算哈希码

答案 4 :(得分:0)

对于大多数字符串,哈希值将在第一次调用hashCode()时计算,或者 - 在多线程场景中 - 每次调用时直到其中一个调用设法计算并缓存其值。但是,包含哈希码计算结果为零的字符序列的字符串实例将在每次调用hashCode()时计算其哈希值。请注意,通过使用散列函数可以避免这种冗余计算,散列函数永远不会为非平凡字符串返回零(例如,通过添加行if (!h) h=value.length+1;),但是改变Java现在可以做到这一点 - - 至少在理论上 - 打破一些现有的代码,假定内置字符串hashCode()已经产生零的任何字符序列将继续这样做直到时间结束。

因为写入String类型的变量只会覆盖包含的引用而不影响它之前引用的String实例,所以与之前字符串的哈希代码无关(包括是否为它的价值尚未计算)将受到转让的影响。

答案 5 :(得分:0)

我看到这个问题仍然“没有回答”。通过谷歌搜索找到它。 所以总结所有答案并增加一些价值:

  • 字符串的hashCode在第一次调用此函数时被缓存,内部字段hashCode为零初始化
  • 字符串是不可变的,但您可以使用Reflection API更改它们。缓存的hashCode仍然不会自动更新
  • 字符常量初始化的字符串总是被实现,所以如果你要写

    public static void main(String[] args) {
        String hello1 = "Hello";
        String hello2 = "Hello";
        System.out.println( hello1 == hello2 );
    }
    

你可以确定它会打印出“真实”。如果你要调用hello1和hello2的hashCode,hashCode只会计算一次,因为它实际上是同一个对象。

希望这些信息对那些通过Google搜索到达那里的人有用。