看了一些非官方的参考文献,并想在此确认我的理解是正确的。假设我们不时添加新的(唯一)元素,
ArrayList<T>
将重新分配内存,因为它的内存需要连续,当新插入的元素的内存增长超过某个阈值时,将重新分配更大的连续内存空间,并且现有元素将被移动到这样的新分配更大的连续存储空间; HashSet<T>
和HashMap<T>
没有这样的问题,因为它们的记忆不需要连续吗?的问候, 林
答案 0 :(得分:2)
如果你在Java 8(jre 1.8.0_71)中检查add(E e)
中ArrayList<>
方法的源代码,它会调用一个名为ensureCapacityInternal(int minCapacity)
的方法。每次将对象添加到ArrayList时都会调用此方法。此inturn调用一系列方法,最后如果ArrayList的大小较小以容纳新添加的元素,则调用名为grow(int minCapacity)
的方法。此方法如下所示:
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
这将创建一个大小比初始大小多1.5倍的新数组,并将旧数组中的所有元素复制到新数组中。这证明了你的观点。 1。
回到你的观点。 2,在HashMap<K,V>
的情况下,它们是一种特殊类型的数组,用于保存键和值对。此阵列插槽称为存储区。因此,您添加到HashMap中的每个对象都应该正确覆盖hashCode()
和equals()
方法。当您调用put(K key, V value)
方法时,它会通过计算您已经传递的键putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)
的#hash来调用名为hash(Object key)
的方法。此哈希表示值对象的存储桶位置。因此,此处的数组仅指示对象所在的地址块。This线程更详细地解释了它。
我希望这就是你要找的东西。