当达到HashMap或HashSet最大容量时会发生什么? [英] What happens when HashMap or HashSet maximum capacity is reached?

查看:243
本文介绍了当达到HashMap或HashSet最大容量时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几分钟后,我回答了一个问题,询问 Java中HashMap的最大可能大小。正如我一直阅读, HashMap是一个可扩展的数据结构。它的大小只受JVM内存大小的限制。 因此,我认为它的大小没有硬限制,并相应地回答。 (同样适用于HashSet。)

Just a few minutes back I answered a question asking about the "Maximum possible size of HashMap in Java". As I have always read, HashMap is a growable data-structure. It's size is only limited by the JVM memory size. Hence I thought that there is no hard limit to its size and answered accordingly. (The same is applicable to HashSet as well.)

但有人纠正我说,因为HashMap的 size()方法返回 int ,则 是对其大小的限制。一个完全正确的点。我只是试图在我的本地测试它,但失败,我需要超过8GB的内存插入超过2,147,483,647整数在HashMap,我没有。

But someone corrected me saying that since the size() method of HashMap returns an int, there is a limit on its size. A perfectly correct point. I just tried to test it on my local but failed, I need more than 8GB memory to insert more than 2,147,483,647 integers in the HashMap, which I don't have.

我的问题是:


  • 当我们尝试在
    HashMap / HashSet中插入2,147,483,647 + 1个元素时会发生什么?

  • 是否抛出错误?

  • 如果是,是哪个错误?如果没有发生什么HashMap / HashSet,它已经
    现有元素和新元素?

如果有人有机会访问一个拥有16GB内存的机器,那么你可以尝试一下。 :)

If someone is blessed with access to a machine with say 16GB memory, you can try it out practically. :)

推荐答案

数组的底层容量必须是2的幂(限制为2 ^ 30)

The underlying capacity of the array has to be a power of 2 (which is limited to 2^30) When this size is reached the load factor is effectively ignored and array stops growing.

此时碰撞的速度增加。

假设hashCode()只有32位,在任何情况下都不会增长太大。

Given the hashCode() only has 32-bits it wouldn't make sense to grow much big that this in any case.

/**
 * Rehashes the contents of this map into a new array with a
 * larger capacity.  This method is called automatically when the
 * number of keys in this map reaches its threshold.
 *
 * If current capacity is MAXIMUM_CAPACITY, this method does not
 * resize the map, but sets threshold to Integer.MAX_VALUE.
 * This has the effect of preventing future calls.
 *
 * @param newCapacity the new capacity, MUST be a power of two;
 *        must be greater than current capacity unless current
 *        capacity is MAXIMUM_CAPACITY (in which case value
 *        is irrelevant).
 */
void resize(int newCapacity) {
    Entry[] oldTable = table;
    int oldCapacity = oldTable.length;
    if (oldCapacity == MAXIMUM_CAPACITY) {
        threshold = Integer.MAX_VALUE;
        return;
    }

    Entry[] newTable = new Entry[newCapacity];
    transfer(newTable);
    table = newTable;
    threshold = (int)(newCapacity * loadFactor);
}

当大小超过Integer.MAX_VALUE时会溢出。

When the size exceeds Integer.MAX_VALUE it overflows.

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或HashSet最大容量时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆