【问题标题】:How does string class does caching of Hashcode in java字符串类如何在java中缓存Hashcode
【发布时间】:2016-01-12 19:19:43
【问题描述】:
Here what is written in String API for 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;
    }

谁能解释这里的缓存是如何发生的?

一条线索是:---- if (h == 0 && value.length > 0) { 代码只会进入这个条件,然后才会计算哈希码,否则会写入相同的内容。但是对于使用 new 创建的两个字符串会发生这种情况:

String a = new String("abc"); 字符串 b = 新字符串(“abc”); 请解释一下

【问题讨论】:

  • 两个不同的Strings 当然不会共享缓存值。

标签: java


【解决方案1】:

但是对于使用 new like 创建的两个字符串会发生这种情况:

String a = new String("abc"); String b = new String("abc"); 

不会发生。仅对单个 String 对象进行缓存。

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

对于单个Stringhash 是存储哈希码的位置。如果是0,那么它会重新计算它——将其存储在局部变量h中——一旦新计算出哈希码,它就会重新存储在hash中,以便将来使用。

如果Strings 是可变的,那么在字符串更改后存储的哈希码将是错误的,因此任何更改字符串的方式都必须将hash 重置为0 以表明它必须重新计算重新。但是,在许多不同的级别上,这会变得很混乱,这就是String 可变的原因。

【讨论】:

  • 您能否解释一下单个字符串对象是如何发生的以及为什么在字符串可变的情况下它不会发生
  • @user3907559 String从不可变。
  • 假设如果字符串是可变的,那么缓存的后果是什么
  • @user3907559 不能这样假设,因为编写代码只是为了处理不可变的,所以如果它是可变的,代码就会失败。因此,假设其他情况是没有意义的。
  • @user3907559 如果字符串被修改,那么您将清除缓存的哈希值,以便下次需要时重新计算哈希值。
【解决方案2】:

每个字符串对象都有一个名为“hash”的字段。每当在字符串对象上调用 hashcode() 时,都会使用“hash”字段的初始值声明一个局部变量 int h。由于初始哈希值为零,因此计算此字符串的哈希值并将其存储在哈希字段中。此后,每当在此字符串上调用 hashcode() 时,都会返回“hash”字段值,因为它将是非零值,因此不会进入 if 条件。

由于String是不可变的,hash值可以被缓存。如果它是可变的,那么这种缓存策略将不起作用。

当您使用 new 创建两个字符串时,它们都是不同的实例,因此每个都有自己的哈希字段。

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];

/** Cache the hash code for the string */
private int hash; // Default to 0
...
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;
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多