Java經典筆試題:能夠手寫一個ArrayList的簡單實現嗎?

Java經典筆試題:能夠手寫一個ArrayList的簡單實現嗎?

面試官Q1:能夠手寫一個ArrayList的簡單實現嗎?面試

咱們都知道ArrayList是基於數組實現,若是讓你實現JDK源碼ArrayList中add()、remove()、get()方法,你知道如何實現嗎?這一節,咱們不看源碼,咱們想一想如何簡單的實現ArrayList幾個基本方法?數組

肯定數據結構

咱們知道,ArrayList中不管什麼數據都能放,是否是意味着它是一個Object類型,既然是數組,那麼是否是Object[]數組類型的?因此咱們定義的數據結構以下:數據結構

private Object[] elementData;  
private int size;

設置自定義的MyArrayList的長度爲10ide

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個元素的時候,顯然沒有地方存放新添加的數據,這個時候咱們須要對數組進行擴容處理學習

對上面代碼作以下修改:this

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

用一張圖來表示就是這樣的:code

Java經典筆試題:能夠手寫一個ArrayList的簡單實現嗎?

查詢數據

接着咱們看一下刪除的操做。ArrayList支持兩種刪除方式:對象

  • 按照下標刪除
  • 按照元素刪除,這會刪除ArrayList中與指定要刪除的元素匹配的第一個元素

對於ArrayList來講,這兩種刪除的方法差很少,都是調用的下面一段代碼:blog

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能夠去回收它

用圖表示是這樣的:

Java經典筆試題:能夠手寫一個ArrayList的簡單實現嗎?

指定位置添加數據

把從指定位置開始的全部元素利用System,arraycopy方法作一個總體的複製,向後移動一個位置(固然先要用ensureCapacity方法進行判斷,加了一個元素以後數組會不會不夠大),而後指定位置的元素設置爲須要插入的元素,完成了一次插入的操做。

public void add(int index,Object obj){
        ensureCapacity();  //數組擴容
        System.arraycopy(elementData, index, elementData, index + 1,
                 size - index);
        elementData[index] = obj;
        size++;
}

用圖表示這個過程是這樣的:

Java經典筆試題:能夠手寫一個ArrayList的簡單實現嗎?

總結一下

從上面的幾個過程總結一下ArrayList的特色:

  • ArrayList底層以數組實現,是一種隨機訪問模式,經過下標索引定位數據,因此查找很是快
  • ArrayList在順序添加一個元素的時候很是方便,只是往數組裏面添加了一個元素而已(這裏指的末尾添加數據)
  • 當刪除元素的時候,涉及到一次元素複製移位,若是要複製的元素不少,那麼就會比較耗費性能
  • 當插入元素的時候,涉及到一次元素複製移位,若是要複製的元素不少,那麼就會比較耗費性能

所以,ArrayList比較適合順序添加、隨機訪問的場景。

寫在最後

歡迎你們關注個人公衆號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裏面更新,整理的資料也會放在裏面。

以爲寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!

相關文章
相關標籤/搜索