首页 > 解决方案 > 如何在 Java 中深度复制哈希器

问题描述

int[]我想在Java中散列大量。我的数组包含从根到树中节点的路径(节点已编号),因此它们在第一个值上非常相似(因为所有路径都来自根)。

我正在使用Google Guava Hasher,我将数组的每个值添加到哈希器以获取 hashCode :

HashFunction hashFunction = Hashing.murmur3_128();
Hasher hasher = hashFunction.newHasher();
for (int i: myArray) {
    hasher.putInt(i);
}
int hashCode = inthasher.hash().asInt();

我想避免为每个路径再次散列整个数组,并且只通过将最后一个值添加到我的散列器副本来散列最后一个值。像这样 :

anotherHasher = hasher.clone();
anotherHasher.putInt(someInt);
int hashCode = hasher.hash().asInt();
int anotherHashCode = anotherHasher.hash().asInt();

但是克隆方法不存在Hasher

这种副本会节省计算时间吗?是否可以Cloneable使用包含 a 的包装器来实现,Hasher即使后者不可克隆?如果是怎么办?还有其他方法吗?

编辑:对于记录,使用 Guava 进行散列需要花费时间的不是添加元素,hasher.putInt(someInt)而是添加最后调用的散列本身hasher.hash()。因此,即使深度复制也很快(不是,请参阅 Tomasz Linkowski 的回答),我的方法不相关,不值得进一步研究。

标签: javahashguava

解决方案


这可以借助执行对象的深拷贝的库来完成(这里有一些深拷贝库的建议)。

一个这样的库是Kryo,可以通过以下方式实现:

  1. 实例化Kryo(请注意,创建此对象非常昂贵+它不是线程安全的):

    Kryo kryo = new Kryo();
    kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
    
  2. 来电Kryo.copy(T)

    Hasher anotherHasher = kryo.copy(hasher)
    

但是,请注意,这可能不会比散列两次更快,因为:

我建议使用Java Microbenchmark Harness对此进行基准测试(请注意链接页面末尾的各种 JMH 插件)。


推荐阅读