【问题标题】:Why is a Java String hash code lazy generated?为什么会延迟生成 Java String 哈希码?
【发布时间】:2012-02-17 00:29:55
【问题描述】:

在java.lang.String.java中出现,Java只会生成hashcode,然后在调用hashcode()之后存储,但是为什么不直接在构造函数中制作hashcode呢?

相关代码:

if (h == 0 && count > 0) {
    int off = offset;
    char val[] = value;
    int len = count;

    for (int i = 0; i < len; i++) {
        h = 31*h + val[off++];
    }

    hash = h;
}

大部分可以放在构造函数中。

【问题讨论】:

  • 如果您找到可接受的答案,您可以勾选它,让人们知道您对您的问题有答案。

标签: java string lazy-initialization


【解决方案1】:

为什么要花时间生成一个很可能不会被使用的哈希码?大多数字符串都是在没有调用 hashcode() 的情况下构造、使用和垃圾收集的。

【讨论】:

  • 许多字符串将在其生命周期中进行相等性检查。如果已经计算了它们的哈希码,则检查两个不相等的字符串是否相等通常非常快。此外,对于一些 hashcode 实现,包括 Java 中的实现,可以在恒定时间(实际上是时间 O(lgN))计算连接两个字符串的 hashcode,但是这个数量是有界的,并且常数项可以相当小)。
【解决方案2】:

Joshua Bloch 将这种做法称为“活泼的单次检查”。

杰里米·曼森 (Jeremy Manson) 很好地解释了为什么这样做以及为什么这样做是安全的:on his blog

本质上,在构建时,您可以通过跳过计算哈希码来节省一些时间。在多线程环境中,您将为此付出代价,因为多个线程可能会执行相同的计算。

【讨论】:

    【解决方案3】:

    这不是真正的正确论坛,问题可能会被关闭。您可以尝试在programmers.stackexchange.com 中询问。

    一个原因可能是计算 hashCode 并不便宜,而且仅在某些情况下才需要。

    【讨论】:

      【解决方案4】:

      2 个原因:

      1) 计算hashCode() 并不便宜:在字符串长度上是O(n) 的复杂性,所以最好只在需要时才这样做。

      和:

      2) 字符串实例是不可变的:因为它们永远不会改变,所以你总是最多计算一次hashCode()

      【讨论】:

        【解决方案5】:

        将它放在构造函数中没有任何好处。但是当它在构造函数中时有一个缺点。当从不调用 String 的 hashCode 时,计算就白费了。当您调用 hashCode() 时,它在两种情况下都会计算一次 - 只是在不同的地点和时间。

        【讨论】:

          猜你喜欢
          • 2014-12-31
          • 2019-04-17
          • 1970-01-01
          • 1970-01-01
          • 2016-06-18
          • 1970-01-01
          • 2012-02-19
          • 2016-07-09
          • 1970-01-01
          相关资源
          最近更新 更多