初始化HashMap的最佳方法

时间:2011-09-25 09:32:45

标签: java optimization data-structures hashmap hashtable

我通常会这样做

HashMap<String,String> dictionary = new HashMap<String,String>();

我开始考虑它,据我所知,HashMap是通过哈希表在引擎盖下实现的。
使用哈希将对象存储在表中,以查找它们应存储在表中的位置。

我没有在dictionary的构造上设置尺寸,这会导致性能下降吗?
即在构造期间哈希表的大小是多少?当元素增加时,它是否需要为表分配新的内存? 或者我对这里的概念感到困惑? 默认容量和负载是否足够,或者我应该花时间查看实际数字?

5 个答案:

答案 0 :(得分:5)

  

我没有在字典构造上设置大小这一事实是否会降低性能?

取决于您在HashMap中存储的数量以及您的代码之后将如何使用它。如果你可以预先给它一个大概的数字,它可能会更快,但是:“如果迭代性能很重要,那么将初始容量设置得太高非常重要”1因为迭代时间是与容量成正比。

在非性能关键的代码片段中执行此操作将被视为过早优化。如果您要超越JDK作者,请确保您的测量结果表明您的优化非常重要。

  

构造期间哈希表的大小是多少?

根据API docs,16。

  

当元素增加时,是否需要为表分配新内存?

是。每次它比负载因子(默认值= .75)更充分时,它会重新分配。

  

默认容量和负载是否足够

只有你可以告诉。对您的计划进行简介,看看它是否在HashMap.put中花费了太多时间。如果不是,请不要打扰。

答案 1 :(得分:4)

关于Java的好处是它是开源的,所以你可以提取source code,这可以回答许多问题:

  1. 不,HashMapHashTable之间没有任何关系。 HashMap来自AbstractMap,并且内部不使用HashTable来管理数据。

  2. 省略显式尺寸是否会降低性能将取决于您的使用模式(或更具体地说,您放入地图的数量)。每次达到某个阈值(0.75 * <current map capacity>)时,地图的大小会自动加倍,并且加倍操作会很昂贵。因此,如果您知道大约将有多少元素进入地图,您可以指定大小并防止它需要分配额外的空间。

  3. 如果使用构造函数指定了地图,则地图的默认容量为16.因此,当第12个元素添加到地图时,它的容量将增加一倍。然后再次在24日,依此类推。

  4. 是的,它需要在容量增加时分配新的内存。这是一项相当昂贵的操作(请参阅resize()transfer()函数)。

  5. 与您的问题无关,但仍值得注意,我建议您声明/实例化您的地图,如:

    Map<String,String> dictionary = new HashMap<String,String>();
    

    ...当然,如果您碰巧知道将在地图中放置多少元素,您也应该指定它。

答案 2 :(得分:1)

如果需要,Hashmap会自动增加大小。初始化的最佳方法是,如果你有某种预期你可能需要多少元素,如果数字很大,只需将它设置为一个不需要不断调整大小的数字。此外,如果您阅读Hashmap的JavaDoc,您会看到默认大小为16,加载因子为0.75,这意味着一旦hashmap为75%已满,它将自动调整大小。因此,如果您希望容纳100万个元素,那么您需要比默认元素更大的尺寸

答案 3 :(得分:1)

首先我会将它声明为接口Map。

Map<String,String> dictionary = new HashMap<String,String>();
  

我是否没有设置构造的大小   字典使性能下降?

是的,应该设置初始容量以获得更好的性能。

  

是否需要为表分配新内存作为元素   增加

是的,负载因素也影响性能。

docs

中的更多细节

答案 4 :(得分:0)

如上所述here,默认初始容量为16,默认加载因子为0.75。您可以使用不同的c'tors更改任何一个,这取决于您的使用情况(尽管这些通常适用于一般用途)。