zoukankan      html  css  js  c++  java
  • 简单复习一下ArrayList的扩容原理

    刚刚跟几个好朋友喝完小酒回家,简单大概复习一下ArrayList的扩容原理,由于头有点小晕,就只大概说一下扩容的原理哈;

    首先ArrayList实现了List接口,继承了AbstractList,大家都知道底层是由数组实现的,但是我们都知道数组是不会增的,那么ArrayList是如何自增扩容的呢?

    我们直接看它的add方法源码

        public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }
    
        private void ensureCapacityInternal(int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
     
            ensureExplicitCapacity(minCapacity);
        }
    
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
     
            // overflow-conscious code
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
    
        private void grow(int minCapacity) {
            int oldCapacity= this.elementData.length;
            int newCapacity= oldCapacity + (oldCapacity >> 1);
            if (newCapacity - minCapacity < 0) {
                newCapacity = minCapacity;
            }
     
            if (newCapacity - MAX_ARRAY_SIZE > 0) {
                newCapacity = hugeCapacity(minCapacity);
            }
     
            this.elementData = Arrays.copyOf(this.elementData, arg2);
        }

    size是当前集合拥有的元素个数,从源码看出,调用了ensureCapacityInternal来保证容量问题,传进去的参数是size+1,保证集合+1之后能够存储下一个数据。

    DEFAULT_CAPACITY是ArrayList定义的静态常量10;

    判断elementData是否是空数组,如果是则取一个较大的值;

    接下来modCount++,这个值说过的,在保证fail-fast机制的时候协助使用的,用于判断集合的结构是否发生了变化;

    新增元素后的长度值减去当前的容量值是否大于0,这里就是判断是否需要扩容的关键方法;

    新长度 = 原长度 + 原长度右移以为位运算   ->   新长度 = 原长度 + 0.5倍原长度

    如果新长度还是小于集合所需最小长度,则把最小长度赋值给新长度;而不进行扩容了;

    如果新长度超过了最大的容量,则调用hugeCapacity方法,这个方法里面判断,源码是一个三元运算:(最小所需长度 > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;

    其实说白了就是调用Arrays.copyOf方法,讲原数组复制到一个新的大容量数组;

  • 相关阅读:
    框架搭建相关
    MVC的优缺点
    java filter、listener、servlet
    java类反射
    oracle创建用户及赋权
    sql分组最大值相关
    oracle备份还原数据库
    Oracle创建DataBase Links
    linux 安装mysql
    网址收藏
  • 原文地址:https://www.cnblogs.com/pengx/p/9616182.html
Copyright © 2011-2022 走看看