zoukankan      html  css  js  c++  java
  • ArrayList增加扩容问题 源码分析

    public class ArrayList<E>{
        private static final int DEFAULT_CAPACITY = 10;//默认的容量是10
        private static final Object[] EMPTY_ELEMENTDATA = {};//长度为空的时候的数组,不可变的
        private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//默认长度的空数组
        transient Object[] elementData; //使用中的临时可变化的数组
        private int size;//数组中的个数
        private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
        protected transient int modCount = 0;//
        
        public void ArrayList(int initialCapacity) {
            if (initialCapacity > 0) {
                this.elementData = new Object[initialCapacity];//新建一个
            } else if (initialCapacity == 0) {
                this.elementData = EMPTY_ELEMENTDATA;//默认是0,就把空数组复制给它
            } else {
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                   initialCapacity);//参数非法异常
            }
        }
    
        public void ArrayList() {
            this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//空参的情况下默认0的数组赋值给它
        }
        
        
        /*增加*/
         public boolean add(E e) {
                ensureCapacityInternal(size + 1);  // Increments modCount!!
                elementData[size++] = e;
                return true;
            }
        
         /*检查是否需要扩容*/
            private void ensureCapacityInternal(int minCapacity) {
                //如果数组是空数组,最小容量赋值为默认10
                if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                    minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
                }
    
                ensureExplicitCapacity(minCapacity);
            }
            /*确定扩容的大小
             * elementData是用来存储实际内容的数组。minExpand 是最小扩充容量。 
             * DEFAULTCAPACITY_EMPTY_ELEMENTDATA共享的空数组实例用于默认大小的空实例。
             * 根据传入的最小需要容量minCapacity来和数组的容量长度对比,若minCapactity大于或等于数组容量,则需要进行扩容。
             * 
             * 
             * */
            private void ensureExplicitCapacity(int minCapacity) {
                modCount++; //AbstractList.class中的值 
    
                // overflow-conscious code 检测到溢出情况下的代码
                //如果最小所需容量>数组长度,就需要扩容 
                if (minCapacity - elementData.length > 0)
                    grow(minCapacity);
            }
            
            /*扩容操作*/
            private void grow(int minCapacity) {
                // overflow-conscious code
                int oldCapacity = elementData.length;
                int newCapacity = oldCapacity + (oldCapacity >> 1);//默认的相当于1.5倍?
                if (newCapacity - minCapacity < 0)
                    newCapacity = minCapacity;//如果还是不够,就把需要的值赋值
                if (newCapacity - MAX_ARRAY_SIZE > 0)
                    newCapacity = hugeCapacity(minCapacity);//判断newCapacity大容量情况,考虑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(); //如果minCapacity小于0 ,内存溢出
                return (minCapacity > MAX_ARRAY_SIZE) ? 
                    Integer.MAX_VALUE : //如果minCapacity也大于MAX_ARRAY_SIZE
                    MAX_ARRAY_SIZE; //否则扩容到MAX_ARRAY_SIZE
            }
            
         /*   综上所述,ArrayList相当于在没指定initialCapacity时就是会使用延迟分配对象数组空间,
            当第一次插入元素时才分配10(默认)个对象空间。假如有20个数据需要添加,那么会分别在第一次的时候,
            将ArrayList的容量变为10 ,之后扩容会按照1.5倍增长。也就是当添加第11个数据的时候,
            Arraylist继续扩容变为10*1.5=15;当添加第16个数据时,继续扩容变为15 * 1.5 =22个
            在JDK1.7中,如果通过无参构造的话,初始数组容量为0,当真正对数组进行添加时,才真正分配容量。
          每次按照1.5倍(位运算)的比率通过copeOf的方式扩容。 
                在JKD1.6中,如果通过无参构造的话,初始数组容量为10.每次通过copeOf的方式扩容后容量为原来的1.5倍加1。
            *
            */
            
    }
  • 相关阅读:
    redis数据结构
    django内置密码原理
    生成图片验证码
    如何封装VUE的axios请求
    杭电1717小数化分数2
    杭电2504 又见GCD
    杭电 2136 Largest prime factor(最大素数因子的位置)
    Linux终端的一些快捷键命令
    杭电 1772 cake
    杭电ACM 1713 相遇周期
  • 原文地址:https://www.cnblogs.com/pikaqiucode/p/8244121.html
Copyright © 2011-2022 走看看