当前位置: 首页 > 知识库问答 >
问题:

HashMap不会根据默认值重新散列

黄淇
2023-03-14

根据Java文件

HashMap的实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的存储桶数,初始容量只是创建哈希表时的容量。负载因子是在哈希表容量自动增加之前允许哈希表达到多少满的度量。当哈希表中的条目数超过负载因子和当前容量的乘积时,哈希表被重新散列(即重建内部数据结构),这样哈希表的存储桶数大约是它的两倍。

 the default initial capacity is 16 and the default load factor is 0.75.

如上所述,HashMap的阈值为12(16*0.75),在放置第13个元素时,应对HashMap进行重新灰化。

我创建了一个空的HashMap,并在其中放置了16个元素。我在调试模式下运行了它。当放置第13个元素时,我检查了调试变量,惊讶地发现阈值仍然是12(而不是24),表数组仍然包含16个条目(而不是32个条目)。只有在放入第16个元素后,哈希表才会重新刷新,使阈值为24(32*0.75)。

我错过了什么吗?

共有1个答案

颛孙成益
2023-03-14

我在HashMap(Java 7)的源代码中找到了答案。输入值将运行以下代码:

public V put(K key, V value) {
    [...]
    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

有趣的调用是添加条目的方法。让我们看看这种方法的来源:

void addEntry(int hash, K key, V value, int bucketIndex) {
    if ((size >= threshold) && (null != table[bucketIndex])) {
        resize(2 * table.length);
        hash = (null != key) ? hash(key) : 0;
        bucketIndex = indexFor(hash, table.length);
    }
    createEntry(hash, key, value, bucketIndex);
}

正如我们所看到的,只有当大小超过阈值并且计算的存储桶(用于放置条目)不为空时,才会进行大小调整。

这种行为是有道理的。只要每个条目进入一个空的bucket,就不需要调整大小,因为每个条目都位于bucket列表的第一位,因此很容易找到。这都是关于性能的。事实上,有许多实现细节表现得非常好。

编辑(因为Java6和Java7之间有区别):

以上源代码来自Java 7。实际上,在Java 6中,大小调整行为只取决于大小和阈值。这是Java 6中addEntry方法的来源:

void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
    table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
    if (size++ >= threshold)
        resize(2 * table.length);
}

这实际上意味着HashMap实现从Java 6更改为Java 7(由于性能原因)。

 类似资料:
  • 我正在使用react在我的网站中切换明暗模式。我还希望主题使用localstorage持久化。问题是,当单击switch切换主题时,相应的localstorage主题值不会更新。我知道状态更新是异步的,但我想解决这个问题。 我的代码: 我尝试使用async await,但结果是一样的。

  • 列插入和更新默认值是指创建 默认值 对于一行中的特定列,INSERT或UPDATE语句正在对该行执行,如果 没有为该列的INSERT或UPDATE语句提供值 . 也就是说,如果一个表有一个名为“timestamp”的列,并且INSERT语句继续执行,但不包括该列的值,则INSERT default将创建一个新值,例如current time,用作要插入“timestamp”列中的值。如果声明 do

  • 我正忙着创建VB. Net Windows应用程序。我正在使用带有名为skedulering的表的microsoft sql服务器数据库。我正在尝试使用基于另一列(即Kode)的唯一值更新一列(即Groep)。此值接受Kode值的前三个字符并向其添加一个整数。我认为我的意思最好用以下内容来解释: 所有红色边框行都具有相同的Groep值。有人能帮我创建sql语句吗? 问候

  • 注:内容翻译自官网文档 Language Guide (proto3) 中的 Default Values 一节 当消息被解析时, 如果被编码的消息没有包含特定的简单元素, 被解析的对象对应的字段被设置为默认值. 默认值是和类型有关的: 对于strings, 默认值是空字符串(注, 是"", 而不是null) 对于bytes, 默认值是空字节(注, 应该是byte[0], 注意这里也不是null)

  • 问题内容: 是否有可能为集合中未找到的所有键返回默认值? 问题答案: [更新] 正如其他答案和评论者所指出的那样,从Java 8开始,您可以简单地调用。 [原版的] 没有Map实现可以完全做到这一点,但是通过扩展HashMap来实现自己的实现很简单:

  • 问题内容: 例如,如果component是一个复选框,则必须将其设置为false,或者是textfield,则必须清除文本。我正在尝试编写一种方法来重置中的所有组件。它必须像HTML表单中的reset函数一样工作。 如何将a重设为默认值? 问题答案: 一种可能的解决方法是创建自定义重置功能。重新初始化面板(您的表单)。 例如 创建一个自定义类来存储表单字段及其侦听器。 重新初始化面板组件将导致按@