初始化HashMap的最佳方法
我通常会这样做
HashMap dictionary = new HashMap();
我开始考虑它,据我所知, HashMap
是通过哈希表实现的。
使用散列将对象存储在表中,以查找它们应存储在表中的位置。
我没有在dictionary
构造上设置大小这一事实是否会降低性能?
即建设期间哈希表的大小是多少? 当元素增加时,是否需要为表分配新内存?
或者我对这里的概念感到困惑?
默认容量和负载是否足够,或者我应该花时间查看实际数字?
我没有在字典构造上设置大小这一事实是否会降低性能?
取决于您将在HashMap
存储多少以及您的代码之后将如何使用它。 如果你可以预先给它一个大概的数字,它可能会更快,但是:“如果迭代性能很重要,那么将初始容量设置得太高非常重要”,因为迭代时间与容量成正比。
在非性能关键的代码片段中执行此操作将被视为过早优化。 如果您要超越JDK作者,请确保您的测量结果表明您的优化很重要。
在构造期间哈希表的大小是多少?
根据API文档 ,16。
当元素增加时,是否需要为表分配新内存?
是。 每次它比负载因子(默认值= .75)更充分时,它会重新分配。
默认容量和负载是否足够
只有你可以告诉。 对程序进行HashMap.put
,看看它是否在HashMap.put
花费了太多时间。 如果不是,请不要打扰。
关于Java的好处是它是开源的,所以你可以提取源代码 ,它回答了许多问题:
-
不,
HashMap
和HashTable
之间没有关系。HashMap
派生自AbstractMap
,并不在内部使用HashTable
来管理数据。 -
省略显式尺寸是否会降低性能将取决于您的使用模式(或更具体地说,您放入地图的数量)。 每当达到某个阈值(0.75 *
)时,地图将自动加倍,并且加倍操作是昂贵的。 因此,如果您知道大约将有多少元素进入地图,您可以指定大小并防止它需要分配额外的空间。 -
如果没有使用构造函数指定,则映射的默认容量为16.因此,当将第12个元素添加到映射时,它将其容量加倍为32。 然后在24日再次,依此类推。
-
是的,它需要在容量增加时分配新的内存。 这是一个相当昂贵的操作(参见
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更改任何一个,这取决于您的使用情况(尽管这些通常适用于一般用途)。