这段代码是java1.8种util.ArrayList中关于数组扩容的一段代码, 上面有一行//overflow-conscious code. 说明下面的代码是对溢出进行考虑的代码 ,但是我花了好多时间在上面仍没有想清楚他是如何避免溢出的, 以及如何在newCapacity溢出的情况下工作的, 望指点迷津
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);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
When the array is about to overflow, add 1/2 of the array, and then compare it with the largest constant of the array. If it exceeds the maximum size of the array, apply for a new one
Integer.MAX_VALUE
的数组,然后把之前旧数组复制过来。其中最难理解的是
>>1
, which is actually equivalent to dividing by 2.Write a simple example and you will know after debugging it
int newCapacity = oldCapacity + (oldCapacity >> 1);
这句执行后如果超过int的最大值那么newCapacity
will be a negative number. This requires understanding the principle of addition and subtraction of binary numbers.The following four sentences are for handling
newCapacity
when overflow becomes a negative numberI think you are talking about operating the same arraylist in multiple threads. At this time, the length overflow problem happened to occur. The problem is that arraylist is not thread-safe. The correct way is to use CopyOnWriteArrayList in java.util.concurrent