Arraylist

作者: 昔日的帅哥 | 来源:发表于2019-06-26 11:16 被阅读0次

    Arraylist

    扩容,为原数组的1.5倍

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//定义一个空数组,跟前面的区别就是这个空数组是用来判断ArrayList第一次添加数据的时候要扩容多少。默认的构造器情况下返回这个空数组
    
    transient Object[] elementData;//数据存的地方,它的容量就是这个数组的长度,同时只要是使用默认构造器(DEFAULTCAPACITY_EMPTY_ELEMENTDATA )第一次添加数据的时候容量扩容为DEFAULT_CAPACITY = 10
    
    private int size;//当前数组的长度
        
    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;
    }
    
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    

    第一种情况:

    当前数组是由默认构造方法生成的空数组并且第一次添加数据。此时minCapacity等于默认的容量(10)那么根据下面逻辑可以看到最后数组的容量会从0扩容成10。而后的数组扩容才是按照当前容量的1.5倍进行扩容。
    

    第二种情况:

    当前数组是由自定义初始容量构造方法创建并且指定初始容量为0。此时minCapacity等于1那么根据下面逻辑可以看到最后数组的容量会从0变成1。这边可以看到一个严重的问题,一旦我们执行了初始容量为0,那么根据下面的算法前四次扩容每次都 +1,在第5次添加数据进行扩容的时候才是按照当前容量的1.5倍进行扩容。
    

    第三种情况:

    当扩容量(newCapacity)大于ArrayList数组定义的最大值后会调用hugeCapacity来进行判断。如果minCapacity已经大于Integer的最大值(溢出为负数)那么抛出OutOfMemoryError(内存溢出)否则的话根据与MAX_ARRAY_SIZE的比较情况确定是返回Integer最大值还是MAX_ARRAY_SIZE。这边也可以看到ArrayList允许的最大容量就是Integer的最大值(-2的31次方~2的31次方减1)。

    不同jdk是不一样的,关于(1.5倍+1)出现在jdk1.6,其他1.7和1.8都是(1.5倍扩容)

    在 Sluggard (Sluggard) 的大作中提到:

    The harm is that the bigger the size of the ArrayList, the more memory allocated to it (which could go to waste if the space is not used). Since increasing the capacity of the ArrayList is much less expensive than increasing the capacity of a HashMap, it makes sense to be more conservative with the increase of capacity of an ArrayList.
    就是说,ArrayList的扩容消费相对HashMap更小,所以允许ArrList更频繁的扩容

    相关文章

      网友评论

          本文标题:Arraylist

          本文链接:https://www.haomeiwen.com/subject/xlnqcctx.html