哪个是HashMap的更好选择?

时间:2011-02-08 11:04:44

标签: java hashmap

使用哪个更好的选择:

为什么?

loadfactor的{​​{1}}属性中的modcountHashMap是什么?

当我在eclipse中调试我的代码并查看HashMap的值时,它会显示一个名为loadfactor的属性,其值为0.75,一个名为modcount的属性值为3。


我在代码中使用hashmap的地方: -

我正在开发一个可以说是聊天应用程序的通信应用程序。其中我将所有发送/接收的消息存储在HashMap中。现在因为我无法假设用户将发送/接收多少消息我声明没有初始容量的hashmap。我写的是

Map<String, Map<String, List<String>>> usersMessagesMap = new HashMap<String, Map<String,List<String>>>();

如果我在初始容量为100或更高的情况下使用它会影响代码吗?

4 个答案:

答案 0 :(得分:8)

您检查过HashMap API Javadoc吗?

  • 容量是哈希表中的存储区数
  • 初始容量只是创建哈希表时的容量
  • 加载系数衡量哈希表在其容量自动增加之前可以获得多长时间

设置初始尺寸太高:

  

迭代收集   观点需要时间成比例   HashMap实例的“容量”   (桶数)加上它的大小   (键值映射的数量)。   因此,不设置非常重要   初始容量太高(或者   加载因子太低)如果迭代   表现很重要。

负载系数对性能的影响:

  

作为一般规则,默认加载   因子(.75)提供了良好的权衡   时间和空间成本之间。更高的   值减少了空间开销但是   增加查询成本(反映在   HashMap的大部分操作   类,包括get和put)。的的   预期的地图条目数   并且应该采用其负载系数   设置初始时考虑在内   容量,以尽量减少数量   重组操作。如果是最初的   容量大于最大值   条目数除以负载   因素,没有任何重组操作   发生。

嗯,简而言之:根据估计的规模和预期的增长率,你必须选择一个近似或相反的方式。

通常,如果您知道Map的初始元素数,建议在构建时设置它,避免在初始化时间提前重新开始。

答案 1 :(得分:4)

如果您知道密钥集大小将远远大于初始容量(which is 16),我会使用更高的初始容量来减少重新散列(随着密钥数量的增长和{{1} } value(其中N/C是存储键的数量,N是地图的容量)达到加载因子,地图数组被扩展并且键被重新定义)。此外,由于地图大小呈指数级增长,除非您拥有大量密钥,否则您不会看到重新散列数量大幅减少。

所以,我的意见是:如果你有备用内存和许多密钥,那么就可以获得更高的初始容量。

答案 2 :(得分:2)

  • 在简单性方面更好,没有初始尺寸。
  • 在性能方面更好,亲自试试。

找到一个SO帖子,Performance of Hashmap with Different Initial Capacity And Load Factor

加载系数

  

大多数碰撞的表现   分辨率方法不依赖   直接在存储的数量n上   条目,但很大程度上取决于   表的负载系数,比率n / s   在n和它的桶的大小s之间   阵列。有时这是指的   作为填充因子,如它所代表的那样   s桶中的部分   充满了其中一个的结构   n个存储的条目。有一个很好的哈希   功能,平均查找成本是   几乎恒定为负载系数   从0增加到0.7(约2/3   完整)左右。      - Wikipedia on Load Factor

现在是您的新问题

  

如果我使用初始容量为   100或更高会影响代码吗?

这不是一个好主意,你可以选择默认的东西。一开始不要过多考虑这个问题。正如他所说,“过早优化是所有邪恶的根源”。无论如何,它都不会带来任何实际好处。

答案 3 :(得分:1)

严格来说,您不应该关心HashMaploadfactormodcount字段的内部字段,而不是属性:属性会有getter / setter。)

modcount很可能是自Map创建以来应用的修改数量。它用于检测并发修改并知道Iterator何时变为“已损坏”(因为原始Map在创建后已经过结构修改)。

loadfactor可能是存储the two-argument constructor的第二个参数的字段。它定义了内部数组在调整大小之前可以“紧密打包”(这会导致所有键的重新散列)。