当我说Java时。
String str= "abcd";
str.hashCode();
我的问题是哈希码是什么时候计算的?@ 第 1 行还是 @ 第 2 行?
我假设,哈希码是预先计算的。每当更新字符串时,哈希码也会“可能”更新。
或者它的另一种方式,即每次调用java 时都会使用此处str.hashCode()
描述的公式计算它。
当我说Java时。
String str= "abcd";
str.hashCode();
我的问题是哈希码是什么时候计算的?@ 第 1 行还是 @ 第 2 行?
我假设,哈希码是预先计算的。每当更新字符串时,哈希码也会“可能”更新。
或者它的另一种方式,即每次调用java 时都会使用此处str.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.hashCode() 方法仅在您调用它时被触发,就像您在 Java 中编写或使用的任何其他方法一样。
因此,要回答您的问题,创建字符串时不会计算哈希码。
如果你看到 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;
}
因此,只有在调用该方法时才会计算哈希码
您不能“更新”字符串。字符串是不可变的。当你“改变”一个字符串实例时,你实际上得到了一个新的字符串实例。
您无法更新现有String
实例,因为String 是 immutable。您将能够做的是创建一个新实例并将其分配给相同的变量。
对于大多数字符串,哈希值将在第一次hashCode()
被调用时计算,或者——在多线程场景中——每次调用它,直到其中一个调用设法计算并缓存它的值。但是,包含哈希码计算为零的字符序列的字符串实例将在每次hashCode()
调用它们时计算其哈希值。请注意,可以通过使用一个哈希函数来避免这种冗余计算,该函数对于非平凡的字符串永远不会返回零(例如,通过添加 line if (!h) h=value.length+1;
),但是现在改变 Java 来做到这一点可能 - 至少在理论上--break 一些现有代码,假设内置字符串hashCode()
曾经产生零的任何字符序列将继续这样做,直到时间结束。
因为写入一个类型的变量String
只会覆盖包含的引用,而不会影响String
它之前引用的实例,所以与之前字符串的哈希码相关的任何内容(包括它的值是否尚未计算)都不会受到影响任务。
我看到这个问题仍然“没有回答”。通过谷歌搜索找到它。因此,总结所有答案并添加更多价值:
由字符常量初始化的字符串总是被保留的,所以如果你写
public static void main(String[] args) {
String hello1 = "Hello";
String hello2 = "Hello";
System.out.println( hello1 == hello2 );
}
您可以确定它会打印出“true”。如果您调用 hello1 和 hello2 的 hashCode,则 hashCode 将只计算一次,因为它实际上是同一个对象。
希望这些信息对那些通过谷歌搜索到达那里的人有用。