简体   繁体   English

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

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

in Java when I say. 在Java中,当我说。

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

My question is When is Hashcode calculated? 我的问题是何时计算哈希码? @ line 1 or @ line 2? @第1行还是@第2行?

I am assuming , that hashcode is pre-computed. 我假设,哈希码是预先计算的。 Whenever string is updated hashcode would also 'perhaps' update. 每当字符串更新时,哈希码也将“可能”更新。

or its the other way ie every time you call str.hashCode() java computes its using the formula that's described here . 或另一种方式,即每次调用str.hashCode() java都会使用此处描述的公式来计算它。

Consistency of hashCode() on a Java string Java字符串上hashCode()的一致性

Strings can't be updated since they're immutable, and the value is cached after it's computed once: 字符串不可更改,因为它们是不可变的,并且值在计算一次之后就被缓存:

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

You cannot "update" a string. 您不能“更新”字符串。 Strings are immutable. 字符串是不可变的。 When you "change" a string instance, you actually get a new string instance. 当您“更改”字符串实例时,实际上会得到一个新的字符串实例。

You can't update existing String instance as String is immutable . 您不能更新现有的String实例,因为String是不可变的 What you will be able to do is create a new instance and assign it to the same variable. 您将能够做的是创建一个新实例,并将其分配给同一变量。

String.hashCode() method is fired only when you call it, just like any other method you write or use in Java. 就像您在Java中编写或使用的任何其他方法一样,只有在调用String.hashCode()方法时才会触发它。

So, to answer your question, the hashcode is not calculated when the String is created. 因此,为回答您的问题,创建字符串时不计算哈希码。

If you see the hashcode method, it's written to calculate only once and saves the precalculated hashcode value to a local variable hash 如果您看到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;
} 

So, the hashcode is calculated only when the method is called 因此,仅在调用方法时才计算哈希码

For most strings, the hash value will be computed the first time hashCode() is called or--in multi-threaded scenarios--every time it's called until one of the calls manages to compute and cache its value. 对于大多数字符串,将在首次调用hashCode()hashCode()或在多线程方案中)每次都调用哈希值,直到每次调用成功计算并缓存其值时才计算哈希值。 String instances containing sequences of characters whose hash code evaluates to zero, however, will have their hash values computed every time hashCode() is called upon them. 字符串实例包含哈希值等于零的字符序列,但是,每次调用hashCode()时,都会计算其哈希值。 Note that it would have been possible to avoid such redundant computation by using a hash function which would never return zero for non-trivial strings (eg by adding the line if (!h) h=value.length+1; ), but changing Java to do that now could potentially--at least in theory--break some existing code that assumes that any sequence of characters for which the built-in string hashCode() has ever yielded zero will continue to do so until the end of time. 注意,通过使用对于非平凡的字符串永远不会返回零的哈希函数,可以避免这种冗余计算(例如, if (!h) h=value.length+1;添加该行,但要进行更改) Java现在这样做(至少在理论上)可能会破坏一些现有代码,这些代码假定内置字符串hashCode()曾经产生零的任何字符序列都将继续这样做直到时间结束。

Because writing to a variable of type String simply overwrites the contained reference without affecting the instance of String to which it had previously referred, nothing related to that previous string's hash-code (including whether or not its value has yet been computed) will be affected by the assignment. 因为写入String类型的变量只会覆盖所包含的引用,而不会影响它先前引用的String实例,所以与该先前字符串的哈希码(包括是否已计算其值)无关的任何内容都不会受到影响。根据任务。

I see this question is still "not answered". 我看到这个问题仍然是“未回答”。 Found it by googling. 通过谷歌搜索找到它。 So to summarize all answers and add some more value: 因此,总结所有答案并增加更多价值:

  • hashCode for Strings are cached on the first call to this function, there is an internal field hashCode which is zero initialized 字符串的hashCode在第一次调用此函数时被缓存,内部字段hashCode初始化为零
  • Strings are immutable, but you can change them using Reflection API. 字符串是不可变的,但是您可以使用Reflection API进行更改。 Still the cached hashCode will not be updated automatically 仍然缓存的hashCode不会自动更新
  • Strings that initialized by character constants are always interned, so if you will write 由字符常量初始化的字符串始终处于intern,因此如果您要编写

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

you can be sure it will print out "true". 您可以确定它会打印出“ true”。 if you will call for hashCode of hello1 and hello2 the hashCode will be calculated only once, since it is actually same object. 如果您要调用hello1和hello2的hashCode,则hashCode仅计算一次,因为它实际上是同一对象。

hope this information will be usefull for those who arrive there by googling. 希望这些信息对通过谷歌搜索到达的人有用。

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

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