JDK1.8下ArrayList的自动扩容机制

ArrayList的几个成员变量

 

    private static final int DEFAULT_CAPACITY = 10;//数组默认初始容量


    /**
     * 定义一个空的数组实例以供其他需要用到空数组的地方调用
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};


    /**
    定义一个空数组,跟前面的区别就是这个空数组是用来判断ArrayList第一添加数据的时候要扩容多少。                
    默认的构造器情况下返回这个空数组
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};


    /**
     * 存数据的地方,它的容量就是这个数组的长度,同时只要是使用默认构造器(DEFAULTCAPACITY_EMPTY_ELEMENTDATA )第一次添加数据的时候容量扩容为DEFAULT_CAPACITY = 10
     */
    transient Object[] elementData; 


    /**
    数组的大小
     */
    private int size;

扩容机制

从add方法说起

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

add方法中调用了ensureCapacityInternal()方法

ensureCapacityInternal 方法

    private void ensureCapacityInternal(int minCapacity) {
        
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }
    private void ensureExplicitCapacity(int minCapacity) {
        //minCapacity是size+1
        modCount++;
        //判断是否需要修改数组大小
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

扩容的重点是grow()方法

    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //新的数组大小是按照原数组大小的1.5倍进行扩容
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //当扩容量(newCapacity)大于ArrayList数组定义的最大值后会调用hugeCapacity            
         来进行判断,会抛出OutOfMemory 内存溢出异常
        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);
    }

 Java容器的快速报错机制ConcurentModificationException

Java容器有一种保护机制,能够防止多个进程同时修改同一个容器的内容。如果你在迭代遍历某个容器的过程中,另一个进程介入其中,并且插入,删除或修改此容器的某个对象,就会立刻抛出ConcurrentModificationException。

    前文提到的迭代遍历指的就是使用迭代器Iterator(ListIterator)或者forEach语法,实际上一个类要使用forEach就必须实现Iterable接口并且重写它的Iterator方法所以forEach本质上还是使用Iterator。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值