簡體   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