【问题标题】:Lazy initialization of hashcode in JavaJava中哈希码的延迟初始化
【发布时间】:2019-04-17 18:35:35
【问题描述】:

为什么我们说不可变对象使用惰性哈希码初始化?对于可变对象,我们只能在需要时才计算哈希码,从而导致延迟初始化?

【问题讨论】:

  • 感觉像是做作业。请在网上搜索“惰性初始化”。
  • @ygor,我已经浏览了给定的帖子。但是我不清楚为什么我们说哈希码方法是为不可变对象延迟初始化的。对于可变对象,我们只能在需要时才计算哈希码,从而导致延迟初始化?
  • 我想这只是措辞的问题。我也不理解“延迟初始化”。缓存主题更有趣。尽管在缓存方面,您可以询问它是惰性的还是急切的(无论方法/值如何)。
  • 顺便说一句,我建议用评论中的信息更新问题。这对理解你的问题很有帮助。 (提示,如果您可以用一两句话提出问题,很可能您可以谷歌搜索,尽管这不是您的情况)

标签: java initialization lazy-evaluation hashcode


【解决方案1】:

对于可变类,存储 hashCode 通常没有多大意义,因为每次修改对象时都必须更新它(或者至少将其取消,以便下次重新计算 hashCode()叫做)。

对于不可变的类,存储哈希码很有意义——一旦计算出来,它就永远不会改变(因为对象是不可变的),也不需要每次hashCode() 都重新计算叫。作为进一步的优化,我们可以避免在第一次需要它之前计算这个值(即,hashCode() 被调用)——即,使用延迟初始化。

没有什么可以阻止您对可变对象执行相同操作,但这通常不是一个好主意。

【讨论】:

  • 当一个对象被用作哈希集合中的键时,它的 hashCode() 不能改变。 +1
【解决方案2】:

延迟初始化的优点是哈希码计算在需要之前被暂停。许多对象根本不需要它,因此您节省了一些计算。特别是当您进行高哈希计算时。看下面的例子:

class FinalObject {
    private final int a, b;
    public FinalObject(int value1, int value2) {
        a = value1;
        b = value2;
    }

    // not calculated at the beginning - lazy once required
    private int hashCode;
    @Override
    public int hashCode() {
        int h = hashCode; // read
        if (h == 0) {
            h = a + b;    // calculation
            hashCode = h; // write
        }
        return h;         // return local variable instead of second read
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    相关资源
    最近更新 更多