初始化HashMap的最佳方法

我通常会这样做

HashMap dictionary = new HashMap(); 

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

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

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

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

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

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

根据API文档 ,16。

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

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

默认容量和负载是否足够

只有你可以告诉。 对程序进行HashMap.put ,看看它是否在HashMap.put花费了太多时间。 如果不是,请不要打扰。

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

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

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

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

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

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

 Map dictionary = new HashMap(); 

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

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

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

 Map dictionary = new HashMap(); 

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

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

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

是的,负载系数也会影响性能。

文档中的更多细节

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