解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
什么是动态扩容机制
动态扩容机制是指,当一个数据结构达到其容量限制时,自动增加容量大小以继续存储新的数据。在动态扩容时,需要考虑到时间和空间的平衡,因为扩容需要分配新的内存空间,在处理大量数据时,需要尽可能减少空间浪费和分配内存的时间消耗。
基于Array的数据结构
Array是一种连续存储的数据结构,可以通过数组下标来访问数据。基于Array的数据结构通常会预先分配一段连续的内存空间作为存储空间,这段空间的大小是有限制的,达到这个限制后需要进行动态扩容。
常见的基于Array的数据结构
常见的基于Array的数据结构包括ArrayList、Deque和Queue等。
示例1:ArrayList
ArrayList是Java中常用的数据结构之一,它是基于Array实现的一种动态数组。当ArrayList中元素的数量超过数组容量限制时,就需要对其进行动态扩容。
在Java中,ArrayList内部维护了一个通过数组实现的elementData数组,当元素的数量超过了数组长度时,需要进行扩容,扩容的实现如下:
/**
* 扩容方法
* newCapacity 扩展空间的大小
*/
private void grow(int newCapacity) {
// 当前容量
int oldCapacity = elementData.length;
// 扩容后数量
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果扩容后元素数量超出容量限制则直接使用Integer.MAX_VALUE为新大小
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
// 复制元素
elementData = Arrays.copyOf(elementData, newCapacity);
}
可以看到,在ArrayList中,扩容时,首先会将旧数组的长度增加50%,然后再根据minCapacity设置扩容后的新长度,如果minCapacity的值小于新长度,则直接将新长度设置为Integer.MAX_VALUE。
示例2:Deque和Queue
Deque是双端队列的一种实现,Queue是队列的一种实现,它们是通过Array实现的。
在Java中,ArrayDeque是Deque的一种实现方式,它的底层是一个循环数组,当数组的大小不足以容纳新的元素时,ArrayDeque采用双倍大小动态扩容机制进行扩容,其扩容实现如下:
/**
* 扩容方法
*/
private void doubleCapacity() {
int addCapacity;
if (head < tail) {
addCapacity = elements.length;
} else {
// 头尾都是指向数组的开头,数组末尾有空闲位置,这种情况下扩容元素个数是elements.length - head
// 头尾相对位置不变,数组末尾无空余位置,这种情况下扩容元素个数是elements.length - head + tail
addCapacity = elements.length - head + tail;
}
// 根据原始数组大小和新增元素个数,计算出新的数组大小
int newCapacity = elements.length << 1;
if (newCapacity < 0) {
throw new IllegalStateException("Sorry, deque too big");
}
Object[] newElements = new Object[newCapacity];
// 复制旧的数组,并修正新数组的起始位置
System.arraycopy(elements, head, newElements, 0, addCapacity);
System.arraycopy(elements, 0, newElements, addCapacity, tail);
elements = newElements;
// 重置头部和尾部的位置
head = 0;
tail = addCapacity;
}
可以看到,在Deque和Queue实现中,扩容时,首先会判断表头和表尾对应的元素位置,然后计算出新数组的长度,并将旧的数据复制到新的数组中。最后,将队列的头部和尾部指针指向新的数组的头尾位置。
结语
基于Array的数据结构的动态扩容机制可以提高数据结构的效率和容量,但扩容时需要考虑到时间和空间的平衡,避免浪费内存和增加内存消耗。通常,动态扩容机制都是内部实现,我们只需要了解其原理和实现过程即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解析从源码分析常见的基于Array的数据结构动态扩容机制的详解 - Python技术站