栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

arraylist扩容机制(arraylist扩容因子)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

arraylist扩容机制(arraylist扩容因子)

ArrayList扩容原理 数据结构

ArrayList的底层数据结构是一个元素类型为Object的数组

构造方法
//默认容量
private static final int DEFAULT_CAPACITY = 10;
//用于空实例的共享空数组实例
private static final Object[] EMPTY_ELEMENTDATA = {};
//共享空数组实例,用于默认大小的空实例。 我们将其与EMPTY_ELEMENTDATA区分开来,以便知道在添加第一个元素时膨胀多少。  
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//数据缓冲区
transient Object[] elementData;
//数组列表长度
private int size;
//无参构造
 public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
//int类型有参构造
public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
    
    

1.当调用无参构造方法时,则将elementData的值设为DEFAULTCAPACITY_EMPTY_ELEMENTDATA。
2.当调用有参构造方法时,若参数大于0,则将elementData设为相应传参大小的Object数组,若参数为0,则将elementData设为EMPTY_ELEMENTDATA 。小于0,则抛出异常。

扩容机制

扩容一般发生在调用add方法向数组中添加元素的时候。

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

1.将当前数组长度size+1传入ensureCapacityInternal方法中,确保数组操作后能容纳下增加add后的值,若创建ArrayList时是无参构造,则将DEFAULT_CAPACITY(10)传入ensureExlicitCapacity方法中(创建长度为10的数组)

if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);

2.在ensureExplicitCapacity方法中,如果当前的数组需求容量(size+1)大于elementData的长度,则进入到grow方法

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

3.在grow方法中,newCapacity为将当前数组长度加上右移一位的长度(1.5倍)与传入的minCapacity比较,若minCapacity比较大,则将数组扩容到成minCapacity长度,(无参第一次扩容时)若newCapacity比较大,则将数组扩容到newCapacity长度(原数组扩容1.5倍的长度)

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);
    }
示例
 public static void main(String[] args) {

        ArrayList objects = new ArrayList<>();
        //当调用无参构造时,数组长度
        System.out.println(getArrayListCapacity(objects));

        objects.add(1);
        //调用add方法
        System.out.println(getArrayListCapacity(objects));

        for (int i=0;i<10;i++){
            objects.add(123);
        }
        System.out.println(getArrayListCapacity(objects));


        ArrayList arrayList = new ArrayList<>(12);
        System.out.println(getArrayListCapacity(arrayList));

        for(int i = 0;i <= 12;i++){
            arrayList.add(456);
        }
        System.out.println(getArrayListCapacity(arrayList));


    }

    //反射获取数组长度
    public static int getArrayListCapacity(ArrayList arrayList){
        Class arrayListClass = ArrayList.class;
        try {
            Field field = arrayListClass.getDeclaredField("elementData");
            field.setAccessible(true);
            Object[] objects =(Object[]) field.get(arrayList);
            return objects.length;
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
            return -1;
        }
    }

输出
0
10
15
12
18


转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号