初始化 HashMap 的最佳方法

发布于 2024-12-06 09:16:39 字数 349 浏览 0 评论 0原文

我通常会这样做,例如

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

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

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

I usually do e.g.

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

I started to think about it, and as far as I know a HashMap is implemented under the hood via a hash table.
The objects are stored in the table using a hash to find where they should be stored in the table.

Does the fact that I do not set a size on the construction of the dictionary makes the performace decrease?
I.e. what would be the size of the hash table during construction? Would it need to allocate new memory for the table as elements increase?
Or I am confused on the concept here?
Are the default capacity and load adequate or should I be spending time for the actual numbers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

星軌x 2024-12-13 09:16:39

Java 的好处在于它是开源的,因此您可以调出 源代码,它回答了一些问题:

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

  2. 省略显式大小是否会降低性能将取决于您的使用模型(或更具体地说,您在地图中放入了多少内容)。每次达到某个阈值(0.75 * <当前地图容量>)时,地图的大小就会自动加倍,而加倍操作的成本很高。因此,如果您知道大约有多少元素将进入映射,您可以指定一个大小并防止它需要分配额外的空间。

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

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

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

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

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

The nice thing about Java is that it is open-source, so you can pull up the source code, which answers a number of questions:

  1. No, there is no relationship between HashMap and HashTable. HashMap derives from AbstractMap, and does not internally use a HashTable for managing data.

  2. Whether or not omitting an explicit size will decrease performance will depend upon your usage model (or more specifically, how many things you put into the map). The map will automatically double in size every time a certain threshold is hit (0.75 * <current map capacity>), and the doubling operation is expensive. So if you know approximately how many elements will be going into the map, you can specify a size and prevent it from ever needing to allocate additional space.

  3. The default capacity of the map, if none is specified using the constructor, is 16. So it will double its capacity to 32 when the 12th element is added to the map. And then again on the 24th, and so on.

  4. Yes, it needs to allocate new memory when the capacity increases. And it's a fairly costly operation (see the resize() and transfer() functions).

Unrelated to your question but still worth noting, I would recommend declaring/instantiating your map like:

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

...and of course, if you happen to know how many elements will be placed in the map, you should specify that as well.

﹂绝世的画 2024-12-13 09:16:39

我在构建字典时没有设置大小是否会导致性能下降?

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

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

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

根据 API 文档, 16.

随着元素的增加,是否需要为表分配新的内存?

是的。每次它比负载因子(默认 = 0.75)更满时,它就会重新分配。

默认容量和负载是否足够

只有您自己知道。分析您的程序,看看它是否在 HashMap.put 上花费了太多时间。如果不是,请不要打扰。

Does the fact that I do not set a size on the construction of the dictionary makes the performace decrease?

Depends on how much you're going to store in the HashMap and how your code will use it afterward. If you can give it a ballpark figure up front, it might be faster, but: "it's very important not to set the initial capacity too high [...] if iteration performance is important" 1 because iteration time is proportional to the capacity.

Doing this in non-performance-critical pieces of code would be considered premature optimization. If you're going to outsmart the JDK authors, make sure you have measurements that show that your optimization matters.

what would be the size of the hash table during construction?

According to the API docs, 16.

Would it need to allocate new memory for the table as elements increase?

Yes. Every time it's fuller than the load factor (default = .75), it reallocates.

Are the default capacity and load adequate

Only you can tell. Profile your program to see whether it's spending too much time in HashMap.put. If it's not, don't bother.

暖风昔人 2024-12-13 09:16:39

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

Hashmap would automatically increase the size if it needs to. The best way to initialize is if you have some sort of anticipating how much elements you might needs and if the figure is large just set it to a number which would not require constant resizing. Furthermore if you read the JavaDoc for Hashmap you would see that the default size is 16 and load factor is 0.75 which means that once the hashmap is 75% full it will automatically resize. So if you expect to hold 1million elements it is natural you want a larger size than the default one

书信已泛黄 2024-12-13 09:16:39

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

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

我没有在构造上设置尺寸吗?
字典使性能下降?

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

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

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

更多详细信息请参见 docs

I would declare it as interface Map first of all.

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

Does the fact that I do not set a size on the construction of the
dictionary makes the performace decrease?

Yes, initial capacity should be set for better performance.

Would it need to allocate new memory for the table as elements
increase

Yes, load factor also effects performance.

More detail in docs

半透明的墙 2024-12-13 09:16:39

此处所述,默认初始值容量为 16,默认负载系数为 0.75。您可以使用不同的 c'tors 更改其中之一,这取决于您的使用情况(尽管这些通常适用于通用目的)。

As stated here, the default initial capacity is 16 and the default load factor is 0.75. You can change either one with different c'tors, and this depends on your usage (though these are generally good for general purposes).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文