zoukankan      html  css  js  c++  java
  • ArrayList源码分析

    ArrayList底层是数组实现的,可以做到动态增长。下面通过简单的源码分析来大致看看ArrayList的添加过程。

    新建一个list 并对add()方法打上断点,debug。

    add()方法如下,size一开始并未赋值  为0

    /**
         * Appends the specified element to the end of this list.
         *
         * @param e element to be appended to this list
         * @return <tt>true</tt> (as specified by {@link Collection#add})
         */
        public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }

    进入到ensureCapacityInternal()方法  此时minCapacity为1  elementData刚开始为  transient Object[] elementData的空数组

    private void ensureCapacityInternal(int minCapacity) {
            ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
        }

    再进入calculateCapacity()方法,此时 DEFAULTCAPACITY_EMPTY_ELEMENTDATA也是一个空数组,

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    而  DEFAULT_CAPACITY一开始默认为10

    由此可见,第一次添加的时候执行 if里面的方法  返回默认长度和minCapacity的最大值也就是10;以后进入由于elementData不为空  因此直接返回minCapacity

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                return Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            return minCapacity;
        }
    1 private void ensureExplicitCapacity(int minCapacity) {
    2         modCount++;
    3 
    4         // overflow-conscious code
    5         if (minCapacity - elementData.length > 0)
    6             grow(minCapacity);
    7     }

    5行此时 minCapacity为默认的10 明显大于一开始的空数组的长度  进入grow();方法  ;同时,该方法也说明只有当minCapacity大于elementData数组长度的时候开始进行扩容。

     1 private void grow(int minCapacity) {
     2         // overflow-conscious code
     3         int oldCapacity = elementData.length;
     4         int newCapacity = oldCapacity + (oldCapacity >> 1);
     5         if (newCapacity - minCapacity < 0)
     6             newCapacity = minCapacity;
     7         if (newCapacity - MAX_ARRAY_SIZE > 0)
     8             newCapacity = hugeCapacity(minCapacity);
     9         // minCapacity is usually close to size, so this is a win:
    10         elementData = Arrays.copyOf(elementData, newCapacity);
    11     }

    第四行新的数组长度为  原数组长度加上原数组长度除以二  此时还是为0,第五行此时新容量小于minCapacity因此新容量就为minCapacity10、

    然后进去第十行对数组进行复制,也就创建了一个长度为10的数组。

     一路返回至add()方法  添加元素  size++

    做个总结,ArrayList默认的数组为0,当第一次添加元素的时候便开始扩容为默认值10。随后如果有数组不断地添加,只有在size大于原数组长度的时候,开始扩容。扩容方法为原长度除以二再加原长度,也就是1.5倍扩容。

    由于水平有限,有错误欢迎指出,一起学习。

  • 相关阅读:
    java 如何判断邮箱是否正确
    Android SDK Manager无法更新的解决
    洛谷P1162
    真 随笔
    初始化结构体
    Linux mkdir -p 后出现permission denied问题
    校赛F
    HDU1022
    UVa156
    HDU1060
  • 原文地址:https://www.cnblogs.com/helloDuo/p/9418554.html
Copyright © 2011-2022 走看看