java - 如何在 Java 中深度复制哈希器

标签 java hash guava

我想用 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 ,可以通过以下方式实现:

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

    Kryo kryo = new Kryo();
    kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
    
  2. 调用Kryo.copy(T):

    Hasher anotherHasher = kryo.copy(hasher)
    

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

  • Kryo 的 StdInstantiatorStrategy 使用 Objenesis实例化 Hasher 实现(我不知道它有多快);
  • 和推荐的 DefaultInstantiatorStrategy 无法使用,因为 Hasher 实现没有无参数构造函数(有关详细信息,请参阅 Kryo 的 readme about InstantiatorStrategy)。

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

关于java - 如何在 Java 中深度复制哈希器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52703510/

相关文章:

java - 如何在部署前设置 Jenkins JDK/Environment?

java - Eclipse 从哪里获取 ${user} ?

perl - Perl 中的哈希复制和删除

java - 使用 Google Guava API 进行过滤

Java Guava 笛卡尔积

java - 将 JButton 放置在图像上

c++ - 用户类型的 hash<T> 仿函数属于哪个命名空间?

git - 如何从(用户)文本内容可靠地重新计算 blob sha1 哈希(或其他身份)并逃脱行尾/空白 hell ?

java - 谷歌集合的多个键和值

java - 如何在 JDBI 中使用 IN 运算符?