本文章的内容基于JDK1.8
直接上源码
public boolean add(E e) {
//最小扩容量
ensureCapacityInternal(size + 1); // Increments modCount!!
//添加元素就是数组赋值
elementData[size++] = e;
return true;
}
接下来看ensureCapacityInternal这个方法如何实现扩容
private void ensureCapacityInternal(int minCapacity) {
//DEFAULTCAPACITY_EMPTY_ELEMENTDATA默认为0
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// 获取默认的容量和传入参数的较大值
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
//具体的扩容机制在这里实现了
ensureExplicitCapacity(minCapacity);
}
接下来看ensureExplicitCapacity
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
//具体的扩容机制在这个方法里实现
grow(minCapacity);
}
接下来看grow
private void grow(int minCapacity) {
// overflow-conscious code
// oldCapacity为旧容量,newCapacity为新容量
int oldCapacity = elementData.length;
//扩容成原来容量的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
//如果新容量小于最小需求容量,就将最小需求容量赋值给新容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
//如果新容量大于数组最大容量就是进入hugeCapacity方法,如果最小需求容量大于数组最大容量就将
//Integer.MAX_VALUE赋值给最小需求容量,如果最小需求容量小于数组最大容量就将Integer.MAX_VALUE-8赋值给最小需求容量
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
//ArrayList的底层就是将原数组复制给新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
接下来看hugeCapacity方法
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
//最小需求容量小于0就会OOM
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
在这里补充一下位运算
我对位运算这块不是很熟悉,但是实践才是检验真理的唯一标准。
从上图的输出结果可以看出(8>>1)=4,(8>>2)=2.这就意味着右移是做缩小运算,左移是做扩大运算。
从>>延伸到>>>
正数还是和>>的计算结果一致,但是负数的区别就大很多了。
这里涉及到正码、反码和补码的知识了,又是我的知识盲区,但是不要紧,可以用代码来打印看看二进制
我自己也没搞懂这个地方,请教了朋友。
他这样解释之后,我似乎明白了点什么。如果有那些地方不对,欢迎指正。