问题描述
几分钟后,我回答了一个问题,询问 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最大容量时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!