coding++:都說新的Arraylist 擴容是(1.5倍+1) 看了1.8的源代碼發現不是這麼回事

 都說新的Arraylist 擴容是(1.5倍+1) 看了1.8的源代碼發現不是這麼回事java

就用下面這段代碼在jdk的三個版本運行看了下效果:this

import java.lang.reflect.Field;
import java.util.ArrayList;
 
public class ArrayListDemo {
 
    public static void main(String[] args) {
        ArrayList<Integer> list1 = new ArrayList<Integer>();
        Integer capacity = getCapacity(list1);// 獲取容量
        int size = list1.size();
        System.out.println("list1的容量:" + capacity);
        System.out.println("list1的大小:" + size);
        System.out.println("----------------------------");
 
        ArrayList<Integer> list2 = new ArrayList<Integer>();
        list2.add(1);
        capacity = getCapacity(list2);// 獲取容量,arraylist初始化容量是10
        size = list2.size();
        System.out.println("list2的容量:" + capacity);
        System.out.println("list2的大小:" + size);
        System.out.println("----------------------------");
 
        ArrayList<Integer> list3 = new ArrayList<Integer>();
 
        capacity = getCapacity(list3);// 獲取容量,arraylist初始化容量是10
        for (int i = 0; i < 10; i++) {
            list3.add(i);
        }
        capacity = getCapacity(list3);
        size = list3.size();
        System.out.println("list3的容量:" + capacity);
        System.out.println("list3的大小:" + size);
        System.out.println("----------------------------");
 
        ArrayList<Integer> list4 = new ArrayList<Integer>();
        for (int i = 0; i < 11; i++) {
            list4.add(i);
        }
        capacity = getCapacity(list4);// 獲取容量
        size = list4.size();
        System.out.println("list4的容量:" + capacity);
        System.out.println("list4的大小:" + size);
 
    }
 
    // 獲取list容量
    public static Integer getCapacity(ArrayList list) {
        Integer length = null;
        Class clazz = list.getClass();
        Field field;
        try {
            field = clazz.getDeclaredField("elementData");
            field.setAccessible(true);
            Object[] object = (Object[]) field.get(list);
            length = object.length;
            return length;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return length;
    }
}

JDK1.6:運行結果:spa

list1的容量:10
list1的大小:0
----------------------------
list2的容量:10
list2的大小:1
----------------------------
list3的容量:10
list3的大小:10
----------------------------
list4的容量:16
list4的大小:11

部分源碼:.net

public void ensureCapacity(int var1) {
    ++this.modCount;
    int var2 = this.elementData.length;
    if (var1 > var2) {
        Object[] var3 = this.elementData;
        int var4 = var2 * 3 / 2 + 1;
        if (var4 < var1) {
            var4 = var1;
        }
 
        this.elementData = Arrays.copyOf(this.elementData, var4);
    }
 
}

JDK1.7:運行結果:code

list1的容量:0
list1的大小:0
----------------------------
list2的容量:10
list2的大小:1
----------------------------
list3的容量:10
list3的大小:10
----------------------------
list4的容量:15
list4的大小:11

部分源碼:blog

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

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == 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) {
    // 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);
}

JDK1.8:運行結果:ci

list1的容量:0
list1的大小:0
----------------------------
list2的容量:10
list2的大小:1
----------------------------
list3的容量:10
list3的大小:10
----------------------------
list4的容量:15
list4的大小:11

部分源碼:element

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // 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);
    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);
}

總結:rem

發現不一樣jdk是不同的,關於(1.5倍+1)出如今jdk1.6,其餘1.7和1.8都是(1.5倍擴容)。get

關於 詳細代碼和原理能夠參考 3。參考1和2也是不錯的!

更多參考:  1: ArrayList擴容1.5倍           2 :ArrayList源碼解析           3 :ArrayList初始默認容量(長度)

相關文章
相關標籤/搜索