Java中哈希码的延迟初始化

时间:2018-11-14 17:58:33

标签: java initialization lazy-evaluation hashcode

为什么我们说不可变对象使用惰性哈希码初始化?对于可变对象,我们也只能在导致延迟初始化的必要条件下计算哈希码吗?

2 个答案:

答案 0 :(得分:4)

对于可变类,通常存储hashCode并没有多大意义,因为每次修改对象时都必须对其进行更新(或至少将其无效,以便您下次{{1 }} 叫做)。

对于不可变类,存储哈希码非常有意义-一旦计算出哈希码,它就永远不会改变(因为对象是不可变的),并且不需要每次{{1} } 叫做。作为进一步的优化,我们可以避免在首次需要该值之前(即调用{ "userName":"Shahabaz Shafi", "userId":12, "dateOfBirth":"1992-01-01", "country":"India", "state":"Karnataka", "city":"Bengaluru", "items":[ { "itemName":"Hamam Soap", "userId":12, "price":20, "TrackLocation":[ { "locationId":1, "at":"2017-10-11", "productTypeName":"Warehouse" }, { "locationId":2, "at":"2017-10-13", "productTypeName":"On Transit" } ] } ] } )来计算该值-即使用惰性初始化。

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

答案 1 :(得分:1)

延迟初始化的优点是,哈希码计算将被挂起,直到需要它为止。许多对象根本不需要它,因此您可以节省一些计算。特别是当您具有较高的哈希计算量时。看下面的例子:

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