当前位置: 代码迷 >> 综合 >> java8 对ArrayList底层扩容的查看
  详细解决方案

java8 对ArrayList底层扩容的查看

热度:41   发布时间:2023-11-23 16:10:29.0

首先我们来看add()方法

public boolean add(E e) {modCount++;//记录此列表被结构修改的次数add(e, elementData, size);//调用私有的add方法return true;}

它调用了另一个私有的方法

private void add(E e, Object[] elementData, int s) {
//如果size等于存储数组的长度,调用grow()方法进行扩容if (s == elementData.length)elementData = grow();//运行到此一定是容量足够的,将传入的对象赋值给存储数组,并记录现有元素的数量elementData[s] = e;size = s + 1;}

那么我们再来看看grow()是怎么扩容的

private Object[] grow() {
//方法体内还调用了真正的扩容方法return grow(size + 1);}
 private Object[] grow(int minCapacity) {//minCapacity接收加入新元素后的size//oldCapacity接收了原存储数组的长度int oldCapacity = elementData.length;//private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//一开始创建的长度为0的存储数组//如果不是第一次调用,则扩容,并将原有数据复制到新数组中,并赋值给原有栈变量,返回存储数组if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {int newCapacity = ArraysSupport.newLength(oldCapacity,minCapacity - oldCapacity, /* minimum growth */oldCapacity >> 1           /* preferred growth */);return elementData = Arrays.copyOf(elementData, newCapacity);} 
//如果是第一次调用add方法,这时候会进入else,新建一个长度为10的数组并返回else {return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];}}

获取新长度的方法,一般情况下是增加为原来的1.5倍

public static int newLength(int oldLength, int minGrowth, int prefGrowth) {// assert oldLength >= 0// assert minGrowth > 0//int prefGrowth首选增长值//int minGrowth最小增长值//int oldLength原长度int newLength = Math.max(minGrowth, prefGrowth) + oldLength;//如果新长度小于可以增加的最大长度,则直接返回这个新长度if (newLength - MAX_ARRAY_LENGTH <= 0) {return newLength;}//返回return hugeLength(oldLength, minGrowth);}
private static int hugeLength(int oldLength, int minGrowth) {int minLength = oldLength + minGrowth;if (minLength < 0) { // overflowthrow new OutOfMemoryError("Required array length too large");}
//如果最小增长值小于等于这个最大长度MAX_ARRAY_LENGTH=MAX_VALUE-8if (minLength <= MAX_ARRAY_LENGTH) {return MAX_ARRAY_LENGTH;}
//否则返回能表示的最大值
//public static final int   MAX_VALUE = 0x7fffffff;return Integer.MAX_VALUE;}

  相关解决方案