我想用 Java 散列大量的 int[]
。我的数组包含从根到树中节点的路径(节点已编号),因此它们在第一个值上非常相似(因为所有路径都来自根)。
我正在使用 Google Guava Hasher ,我将数组的每个值添加到哈希器以获取哈希码:
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
不存在克隆方法。
这种复制会节省计算时间吗?是否可以使用包含 Hasher
的包装器实现 Cloneable
,即使后者不可克隆?如果是如何?还有别的办法吗?
编辑: 根据记录,使用 Guava 进行散列运算需要时间的不是使用 hasher.putInt(someInt)
添加元素,而是散列运算本身在末尾调用hasher.hash()
。因此,即使是深度复制也很快(但事实并非如此,请参阅 Tomasz Linkowski 的回答),我的方法不相关,不值得进一步研究。
最佳答案
这可以在执行 deep copy 的库的帮助下完成一个对象(这里有一些 deep copy library recommendations )。
一个这样的图书馆是Kryo ,可以通过以下方式实现:
实例化
Kryo
(请注意,此对象的创建非常昂贵 + 它不是线程安全的):Kryo kryo = new Kryo(); kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
调用
Kryo.copy(T)
:Hasher anotherHasher = kryo.copy(hasher)
但是,请注意,这可能不会比散列两次更快,因为:
- Kryo 的
StdInstantiatorStrategy
使用 Objenesis实例化Hasher
实现(我不知道它有多快); - 和推荐的
DefaultInstantiatorStrategy
无法使用,因为Hasher
实现没有无参数构造函数(有关详细信息,请参阅 Kryo 的 readme aboutInstantiatorStrategy
)。
我建议使用 Java Microbenchmark Harness 对此进行基准测试(注意链接页面末尾的各种 JMH 插件)。
关于java - 如何在 Java 中深度复制哈希器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52703510/