2012-02-18 43 views
0

从Java的约Hashtable类的文档,它说为什么Hashtable的负载因子与CLRS书中描述的负载因子不一致?

作为一般规则,默认加载因子(.75)

因此加载时间和空间成本上寻求一种折衷Hashtable的因子是0.75,这意味着如果有N个密钥,Hashtable将使用M = N/0.75个空间来存储它们。

在CLRS书中,它还引入了负载因子alpha。但是从我的理解来看,CLRS打算设置大于1的α,即M = N/alpha < N.这意味着Hashtable可以使用M个时隙,这样它可以节省未使用密钥的存储空间。

我说M < N可以节省存储空间,因为通常我们不知道N的确切值,但是我们知道这组密钥并使用N代表可能的密钥数量。这组键可能非常大,但实际使用的键的数量非常小。因此设置小于N的M可以节省存储空间。这也是为什么通常Hashtable不使用直接数组映射每个{key,value} 1:1的原因。

但Java中的哈希表使用的存储量超过了N.我认为它与CLRS设计不一致,对吧?

对吗?

谢谢

回答

2

那么,负载系数应该大于添加的元素。除以小于1的数字会导致比初始数字更大的数字。

假设你要添加100元,你可以一次:

AllocationSize = 100/0.75; // Your formula: M = N/0.75 

AllocationSize = 100 * 1.33333333; // M = N/X -> M = N * (1/X) 

其中两个结果133.333333 - >133

整个的JavaDoc:

哈希表的实例有影响其性能 两个参数:初始容量和负载因子。容量是散列表中的桶数 ,初始容量是 ,仅仅是创建哈希表时的容量。请注意, 散列表处于打开状态:在“散列冲突”的情况下,单个 存储区存储多个条目,这些条目必须按顺序搜索。 负载因子是衡量在其容量自动增加之前,散列表被允许达到多少满的程度。当散列表中的 条目的数量超过了当前容量的负载因子和 的乘积时,通过调用rehash 方法增加容量。

通常,默认加载因子(.75)在时间和空间成本之间提供良好折衷 。较高的值会减少空间开销 ,但会增加查找条目的时间成本(其中 反映在大多数哈希表操作中,包括get和put)。

初始容量控制浪费空间和需要重新哈希操作的耗时之间的权衡。如果初始容量大于Hashtable将包含的最大条目数量除以其 负载因子,则不会发生重新操作 操作。但是,将初始容量设置得太高可能会浪费空间。

如果许多项将被制作成一个Hashtable,具有 足够大的容量创建它可以允许条目不是让根据需要 生长表它执行自动重散列插入更有效地 。

+0

是的,我知道计算。我的问题是为什么它将allocationsSize设置为大于N?我认为不使用直接数组映射的Hashtable的一点是保存存储。但是将allocationSize设置为大于N是浪费,对吧? – 2012-02-18 09:26:40

+0

关于HashMap的'whole' javadoc提供了更多信息。使N大于1是无稽之谈。访问时间将极其缓慢,整个HashMap将“无用”。 – poitroae 2012-02-18 09:33:41

0

我还没有听说过CLRS书籍,但我可以告诉你使用大于0.75的加载因子(对于某些散列图设计甚至更少)会导致大量冲突。

如果您允许HashMap或Hashtable自然增长,其容量将与条目数成比例。与Entry对象的大小(通常为16-24字节)相比,这些引用很小(通常为4个字节),因此您关心的哈希索引表总是比Entry对象的大小小几倍,更不用说关键字了和价值。

相关问题