使用哪个更好的选择:
HashMap
with initial size:HashMap hm = new HashMap(10);
或HashMap
without initial size:HashMap hm = new HashMap()
? 为什么?
loadfactor
的{{1}}属性中的modcount
和HashMap
是什么?
当我在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或更高的情况下使用它会影响代码吗?
答案 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)
严格来说,您不应该关心HashMap
(loadfactor
和modcount
字段的内部字段,而不是属性:属性会有getter / setter。)
modcount
很可能是自Map
创建以来应用的修改数量。它用于检测并发修改并知道Iterator
何时变为“已损坏”(因为原始Map
在创建后已经过结构修改)。
loadfactor
可能是存储the two-argument constructor的第二个参数的字段。它定义了内部数组在调整大小之前可以“紧密打包”(这会导致所有键的重新散列)。