Java經典筆試題:可以手寫一個ArrayList的簡單實現嗎?
面試官Q1:可以手寫一個ArrayList的簡單實現嗎?
我們都知道ArrayList是基於陣列實現,如果讓你實現JDK原始碼ArrayList中add()、remove()、get()方法,你知道如何實現嗎?這一節,我們不看原始碼,我們想想如何簡單的實現ArrayList幾個基本方法?
確定資料結構
我們知道,ArrayList中無論什麼資料都能放,是不是意味著它是一個Object型別,既然是陣列,那麼是不是Object[]陣列型別的?所以我們定義的資料結構如下:
private Object[] elementData;
private int size;
設定自定義的MyArrayList的長度為10
public MyArrayList(){ this(10); } public MyArrayList(int initialCapacity){ if(initialCapacity<0){ try { throw new Exception(); } catch (Exception e) { e.printStackTrace(); } } elementData = new Object[initialCapacity]; }
有了存放資料的位置,接下來,我們想想如何將資料放入陣列?
新增資料
public void add(Object obj){
elementData[size++]=obj;
}
每新增一個元素,size就會自增1,我們定義的陣列長度為10,當我們新增到11個元素的時候,顯然沒有地方存放新新增的資料,這個時候我們需要對陣列進行擴容處理
對上面程式碼做如下修改:
public void add(Object obj){ if(size==elementData.length){ //建立一個新的陣列,並且這個陣列的長度是原陣列長度的2倍 Object[] newArray = new Object[size*2]; //使用底層拷貝,將原陣列的內容拷貝到新陣列 System.arraycopy(elementData, 0, newArray, 0, elementData.length); //並將新陣列賦值給原陣列的引用 elementData = newArray; } //新來的元素,直接賦值 elementData[size++]=obj; }
用一張圖來表示就是這樣的:
查詢資料
接著我們看一下刪除的操作。ArrayList支援兩種刪除方式:
- 按照下標刪除
- 按照元素刪除,這會刪除ArrayList中與指定要刪除的元素匹配的第一個元素
對於ArrayList來說,這兩種刪除的方法差不多,都是呼叫的下面一段程式碼:
public void remove(int index){
//刪除指定位置的物件
//a b d e
int numMoved = size - index - 1;
if (numMoved > 0){
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
}
elementData[--size] = null; // Let gc do its work
}
其實做的事情就是兩件:
- 把指定元素後面位置的所有元素,利用System.arraycopy方法整體向前移動一個位置
- 最後一個位置的元素指定為null,這樣讓gc可以去回收它
用圖表示是這樣的:
指定位置新增資料
把從指定位置開始的所有元素利用System,arraycopy方法做一個整體的複製,向後移動一個位置(當然先要用ensureCapacity方法進行判斷,加了一個元素之後陣列會不會不夠大),然後指定位置的元素設定為需要插入的元素,完成了一次插入的操作。
public void add(int index,Object obj){
ensureCapacity(); //陣列擴容
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = obj;
size++;
}
用圖表示這個過程是這樣的:
總結一下
從上面的幾個過程總結一下ArrayList的特點:
- ArrayList底層以陣列實現,是一種隨機訪問模式,通過下標索引定位資料,所以查詢非常快
- ArrayList在順序新增一個元素的時候非常方便,只是往數組裡面添加了一個元素而已(這裡指的末尾新增資料)
- 當刪除元素的時候,涉及到一次元素複製移位,如果要複製的元素很多,那麼就會比較耗費效能
- 當插入元素的時候,涉及到一次元素複製移位,如果要複製的元素很多,那麼就會比較耗費效能
因此,ArrayList比較適合順序新增、隨機訪問的場景。
寫在最後
歡迎大家關注我的公眾號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裡面更新,整理的資料也會放在裡面。
覺得寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!