繁体   English   中英

Java中的String hashCode是否已预先计算?

[英]Are String hashCode in java pre-computed?

在Java中,当我说。

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

我的问题是何时计算哈希码? @第1行还是@第2行?

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

或另一种方式,即每次调用str.hashCode() java都会使用此处描述的公式来计算它。

Java字符串上hashCode()的一致性

字符串不可更改,因为它们是不可变的,并且值在计算一次之后就被缓存:

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

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

您不能更新现有的String实例,因为String是不可变的 您将能够做的是创建一个新实例,并将其分配给同一变量。

就像您在Java中编写或使用的任何其他方法一样,只有在调用String.hashCode()方法时才会触发它。

因此,为回答您的问题,创建字符串时不计算哈希码。

如果您看到hashcode方法,那么它将被编写为仅计算一次,并将预先计算的hashcode值保存到本地变量hash

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

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

对于大多数字符串,将在首次调用hashCode()hashCode()或在多线程方案中)每次都调用哈希值,直到每次调用成功计算并缓存其值时才计算哈希值。 字符串实例包含哈希值等于零的字符序列,但是,每次调用hashCode()时,都会计算其哈希值。 注意,通过使用对于非平凡的字符串永远不会返回零的哈希函数,可以避免这种冗余计算(例如, if (!h) h=value.length+1;添加该行,但要进行更改) Java现在这样做(至少在理论上)可能会破坏一些现有代码,这些代码假定内置字符串hashCode()曾经产生零的任何字符序列都将继续这样做直到时间结束。

因为写入String类型的变量只会覆盖所包含的引用,而不会影响它先前引用的String实例,所以与该先前字符串的哈希码(包括是否已计算其值)无关的任何内容都不会受到影响。根据任务。

我看到这个问题仍然是“未回答”。 通过谷歌搜索找到它。 因此,总结所有答案并增加更多价值:

  • 字符串的hashCode在第一次调用此函数时被缓存,内部字段hashCode初始化为零
  • 字符串是不可变的,但是您可以使用Reflection API进行更改。 仍然缓存的hashCode不会自动更新
  • 由字符常量初始化的字符串始终处于intern,因此如果您要编写

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

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

希望这些信息对通过谷歌搜索到达的人有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM