search

Home  >  Q&A  >  body text

java - ArrayList的数组扩容是如何考虑溢出的?

这段代码是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;
}
阿神阿神2818 days ago882

reply all(3)I'll reply

  • 高洛峰

    高洛峰2017-04-18 09:40:39

    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 oneInteger.MAX_VALUE的数组,然后把之前旧数组复制过来。
    其中最难理解的是>>1, which is actually equivalent to dividing by 2.

    reply
    0
  • 高洛峰

    高洛峰2017-04-18 09:40:39

    Write a simple example and you will know after debugging it

    public static void main(String[] args) {
        int oldCapacity = Integer.MAX_VALUE - 16;
        System.out.println(oldCapacity);
        int minCapacity = Integer.MAX_VALUE - 15;
        int maxSize = Integer.MAX_VALUE - 8;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
    
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - maxSize > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        System.out.println(newCapacity);
    }
    
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > Integer.MAX_VALUE - 8) ?
                Integer.MAX_VALUE :
                Integer.MAX_VALUE - 8;
    }

    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 newCapacitywhen overflow becomes a negative number

    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - maxSize > 0)
        newCapacity = hugeCapacity(minCapacity);

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 09:40:39

    I 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

    reply
    0
  • Cancelreply