java中ArrayList 遍歷方式、默認容量、擴容機制


 

遍歷

先定義ArrayList,並填充數據

                //定義集合
        ArrayList arr = new ArrayList<>();
        //添加數據
        for(int i = 0; i < 10; i ++) {
            arr.add(i);
        }        

 

 

 

1、下標遍歷

for (int i = 0; i < arr.size(); i++) {
    System.out.println(arr.get(i));
}

2、foreEach (jdk 1.5 及以上可用)

for (int i = 0; i < arr.size(); i++) {
    System.out.println(arr.get(i));
}

3、java 8 新特性 Lambda表達式 (jdk 1.8 及其以上)

arr.forEach(x -> System.out.println(x));

4、Iteraotr迭代器

Iterator iterator = arr.iterator();
while(iterator.hasNext()) {
    System.out.println(iterator.next());
}

5、ListIterator 迭代器 (這個是List集合特有的)

//List轉用迭代
ListIterator listIterator = arr.listIterator();
//從前往后
System.out.println("listIterator 從前往后 ");
while(listIterator.hasNext()) {
    System.out.println(listIterator.next());
}

//從后往前
System.out.println("listIterator 從后往前 ");
while(listIterator.hasPrevious()) {
    System.out.println(listIterator.previous());
}

 

默認容量,和擴容機制

默認容量為10,有圖有真相:

擴容機制,先看一下擴容的源代碼吧:

    //minCapacity 代表着最小擴容量
    private void grow(int minCapacity) {
        // overflow-conscious code
        //elementData 是 ArrayList存儲數據的數組 這里是獲取當前數組的長度
        int oldCapacity = elementData.length;
        //計算擴容后的數組長度 = 當前數組長度  + (當前數組長度 * 0.5) ;也就是擴容到當前的 1.5 倍
        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);
    }

 

恩,也就是說ArrayList通常的套路是當容量不足時就擴容到當前容量的 1.5被。下面我通過java反射機制證明這一點:

public static void main(String[] args) throws Exception {
        ArrayList a = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            a.add(i);
            print(a);
        }
    }
    static void print(List list) throws Exception {
        Class c = list.getClass();
        //elementData 就是ArrayList用於底層存儲數據的數組,
        //我們通過觀察數組長度的變化來證明我們所說的擴容機制正確性
        Field  f = c.getDeclaredField("elementData");
        //設置可訪問
        f.setAccessible(true);
        //反射對象
        Object[] elementData = (Object[])f.get(list);
        System.out.println("elementData.length" + elementData.length + ",size" + list.size());
    }

下面時執行結果:

elementData.length10,size1
elementData.length10,size2
elementData.length10,size3
elementData.length10,size4
elementData.length10,size5
elementData.length10,size6
elementData.length10,size7
elementData.length10,size8
elementData.length10,size9
elementData.length10,size10
elementData.length15,size11
elementData.length15,size12
elementData.length15,size13
elementData.length15,size14
elementData.length15,size15
elementData.length22,size16
elementData.length22,size17
elementData.length22,size18
elementData.length22,size19
elementData.length22,size20
elementData.length22,size21
elementData.length22,size22
elementData.length33,size23
elementData.length33,size24
elementData.length33,size25
elementData.length33,size26
elementData.length33,size27
elementData.length33,size28
elementData.length33,size29
elementData.length33,size30

ArrayList擴容是向上取整還是向下取整?

int newCapacity = oldCapacity + (oldCapacity >> 1);

oldCapacity >> 1 就是 oldCapacity * 0.5 jdk人員將它設計成這樣是為了更高的效率。記住  oldCapacity >> 1 是向下取整 。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM