在Java中哈希码斗分布(Hashcode bucket distribution in java)

2019-06-26 06:26发布

假设我需要存储在1000个的Hashset目的,是更好的是我有一个包含每个对象1000桶(由散列码生成唯一值针对每个对象),或具有10桶大致含有100个对象?

1个优势具有独特的桶是我可以节省执行周期上调用equals()方法?

为什么是重要的是要有桶的设置数量和amoung他们尽可能均匀地分布对象?

什么应该是斗比理想对象?

Answer 1:

为什么是重要的是要有桶的设置数量和amoung他们尽可能均匀地分布对象?

HashSet应该能够确定成员O于平均(1)时间。 从文档 :

这个类提供了基本操作(添加,删除,包含和大小)固定的时间性能,假定哈希函数将分散的桶中正确的元素。

一个算法Hashset用来实现这一目标是检索对象的哈希代码并使用它来找到正确的桶。 然后,它遍历在桶中的所有项目,直到找到一个相等。 如果物品的桶中的数量大于O(1),然后查找会比O(1)时间。

在最坏的情况下 - 如果所有项目散列到同一个桶 - 这将需要O(n)的时间来确定对象是否在集合。

什么应该是斗比理想对象?

这里有一个时空权衡。 增加桶的数量减少冲突的机会。 然而,它也增加了内存的需求。 该哈希集合有两个参数initialCapacityloadFactor ,让您调整多少桶HashSet应该创建。 默认加载因子为0.75,这是适用于大多数的目的,但如果你有特殊的要求,你可以选择其他的价值。

有关这些参数的详细信息可以在文档中找到HashMap

这种实施方式提供基本操作(get和put)稳定的性能,假定哈希函数将分散的桶中正确的元素。 遍历所有收集的意见需要时间成正比的HashMap实例的“容量”(桶的数量),加上它的大小(键值映射关系数)。 因此,不要将初始容量设置得太高(或负载因数过低),如果迭代性能很重要,非常重要。

HashMap中的一个实例具有影响其性能的两个参数:初始容量和负载因子。 容量是在哈希表中桶的数量,和初始容量是简单地在创建哈希表中的时间的能力。 加载因子是哈希表是如何充分允许获得之前它的容量自动增加的措施。 当在散列表中的条目的数量超过了负载因数和电流容量的乘积,容量大致由调用翻版方法一倍。

作为一般规则,默认加载因子(.75)在时间和空间成本之间的良好平衡。 较高的值降低开销的空间,但增加了查找成本(反映在大多数HashMap类,包括get的操作,并把)。 在图及其负载因子条目的预期数量应设置其初始容量的情况下,以最小化翻版操作的次数加以考虑。 如果初始容量大于负载系数分项的最大数量,则永远不会发生rehash操作。



Answer 2:

大约每个元素一个桶是处理器更好,太多的桶是坏的记忆。 Java将开始提着水桶少量,并自动增加你的HashSet的能力,一旦开始加注,所以你并不真正需要关心,除非你的应用有问题的表现,你已经确定了一个HashSet的原因。

如果每个桶你几个元素,查找开始服用更长的时间。 如果你有大量的空水桶中,你正在使用更多的内存比你需要和遍历元素需要更长的时间。

这似乎是一个不成熟的优化等待,虽然发生 - 默认的构造在大多数情况下的罚款。



Answer 3:

Object.hashCode()的类型为int ,你只能有2 ^ 32个不同的值,这就是为什么你创建桶和它们之间分配的对象。

编辑:如果您使用的是2^32桶储存2 ^ 32的对象,然后挑衅获取操作会给你不断的复杂性,但是当你被一个元素插入一个存储2^32的对象,然后再次提出将不是方法执行,如果我们使用Object[]作为桶则每次它超过的长度array会造成更大的尺寸新数组和复制内容纳入于此。 这一过程会增加复杂性。 这就是为什么我们使用的equalshashcode中的比例和通过做Hashsets本身通过提供更好的hashing algorithm



文章来源: Hashcode bucket distribution in java