java - 如何在 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 的回答),我的方法不相关,不值得进一步研究。
解决方案
这可以借助执行对象的深拷贝的库来完成(这里有一些深拷贝库的建议)。
一个这样的库是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 的自述InstantiatorStrategy
文件)。
我建议使用Java Microbenchmark Harness对此进行基准测试(请注意链接页面末尾的各种 JMH 插件)。
推荐阅读
- php - URL重写和Wordpress?
- python - 以元组作为参数解包 UDF 中的元组
- javascript - FileReader:reader.result 显然不是 null
- windows - (如何)使用 `hSource` 句柄获取有关 `TOUCINPUT` 源设备的附加信息?
- python - Python中的多类和多标签分类模型?
- java - 未知字段操作(服务:AmazonIdentityManagement;状态代码:400)
- php - 在 CronJobs 之间传递信息
- java - 如何将名称添加到 JSON 数组中的列表,使用 springboot 发布响应
- python - 使用 python selenium 按下 F 键——切换阅读器视图
- python - Matplotlib 动画保存方法返回创建具有意外帧数的静态图像