如何在hashmap中创建存储区?

时间:2015-05-03 19:23:34

标签: java collections

我对哈希映射的内部工作有点困惑。 我创建了一个默认容量为16的Hashmap,我的密钥类总是返回一个哈希码值1.所以当我将第13个元素输入到这个地图时,它会使地图​​大小加倍。
1.哈希映射中会有多少个桶?
2.哈希映射是否按需创建新存储桶(即当哈希码与任何现有存储桶的哈希码值不匹配时)?

3 个答案:

答案 0 :(得分:3)

虽然时间有点晚,但这可能有助于其他用户寻找这个问题的答案。

从第一个问题开始,哈希映射中会有多少个桶? - 如果你在实例化HashMap时没有在构造函数参数中指定它,那么将有16个桶作为默认容量。

现在让我们来看第二个问题,即哈希映射是否按需创建新桶(即当哈希码与任何现有存储桶的哈希码值不匹配时)?

看看Hashmap的put方法here的实现会很有趣。

public V put(K key, V value) {

    if (key == null)
        return putForNullKey(value);

    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);

    for (Entry<K, V> e = table[i]; e != null; e = e.next) {
        Object k;

        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }
    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

如果仔细观察,在put方法中调用接受键的hashmap作为参数的方法 hash 。这种方法的工作是防止质量差的哈希函数。在使用此 indexFor 方法之后,标识将插入元素的索引(存储区)。此方法返回的索引始终指向现有存储桶。因此,不存在密钥的哈希码指向不存在的存储桶的情况。

那么hashmap何时创建一个新的存储桶?它在javase docs中得到了很好的解释。

它说:&#34; HashMap的一个实例有两个影响其性能的参数:初始容量和负载因子。容量是哈希表中的桶数,初始容量只是创建哈希表时的容量。加载因子是在自动增加容量之前允许哈希表获取的完整程度的度量。当哈希表中的条目数超过加载因子和当前容量的乘积时,哈希表将被重新哈希(即,重建内部数据结构),以便哈希表具有大约两倍的桶数。 &#34;

希望有所帮助。

答案 1 :(得分:0)

当您使用默认容量(16)创建HashMap时,可以使用16个桶创建它(即容量==桶数)。

  1. 当容量加倍时,桶的数量翻倍。

  2. hashCode始终匹配某个现有存储桶,因为模数N(其中N是当前容量)应用于计算的哈希,以便找到它所属的存储桶。

答案 2 :(得分:0)

我更多来自C#,但Java与它非常相似:) 如果有任何错误,请原谅我。随意纠正它。

无法轻松告知可用存储桶的数量。它取决于地图中的元素数量(加载因子)。负载系数保持在总容量的75%左右。这与以下事实有关:如果存在两个相同的哈希值,则必须对其中一个进行重新哈希(以在地图中获得另一个位置) - &gt; 75%是性能和尺寸之间的良好权衡。每当超过75%时,尺寸加倍(即16%的75%为12;第13个元素的尺寸加倍)。无论如何,这也是第二个问题的答案。