Java的ArrayList(面試必須瞭解)——分析源碼裏的擴容機制(代碼示例+圖文)

面試可能會聊到ArrayList的擴容機制:首次分配大小爲10的一個容量,超過10的容量那麼就會以1.5倍擴容

舉個通俗的例子:你是個老闆,最開始你有5個員工分別要住5個房間,ArrayList很大方,首次就直接分配10個房間給你。後來你的事業蒸蒸日上,你的員工越來越多,有11個員工了,住不下原來的10個房間,那麼我ArrayList以原來已經住的房間(10個的房間)的1.5倍方式開房間給你員工住。

結合上面列子和下面的圖,可能會讓你更加深理解
在這裏插入圖片描述
(原來10個房間 × 1.5 = 15房間,15個房間 × 1.5 = 22房間)

代碼實例

首先創建一個ArrayList,調用add,然後點擊add方法裏面的源碼看看究竟吧!

ArrayList<String> arraylist = new ArrayList<String>();
arraylist.add("hello");

可以看到add的一個函數,它先調用ensureCapacityInternal,是不是不知道它是幹啥的,從字面意思理解的話是確保容量足夠的,再點擊看它的源碼

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

嗯…我去,又調了一個ensureExplicitCapacity,還有calculateCapacity,那就先看看
calculateCapacity

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

它會判斷數組是否爲空,如果爲空,首次分配容量的值爲10,它的常量:DEFAULT_CAPACITY = 10(這裏確保容量足夠)

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
       return Math.max(DEFAULT_CAPACITY, minCapacity);
      }
      return minCapacity;
    }

接下來調用ensureExplicitCapacity,判斷當數據大於當前數組,那麼調用grow

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

實現擴容的方法正是:grow

主要gorw方法裏這句,oldCapacity右移1(相當於除以2),再加上oldCapacity(可以理解就是1.5倍)賦值給newCapacity。如果擴展還是小於minCapacity,就擴展minCapacity

int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity -minCapacity < 0)
newCapacity = minCapacity;
在這裏插入圖片描述

最後

你會發現看源碼有點像剝洋蔥,一層層的剝,不知道到什麼時候你已經淚流滿面了,當然只是個ArrayList還不至於啦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章