100行程式碼手寫模擬一個ArrayList
一、ArrayList
首先ArrayList是一個List集合,底層的實現原理是陣列,因此我們來手寫模擬一下ArrayList,順便複習下陣列和資料結構。
二、結果演示:
2.1、測試add()、set()、get()方法
2.2、測試clear()方法
2.3、測試remove()方法
三、實現思路
get() 實現思路:
首先,需要自定義一個Object型別的陣列用來存放資料,然後再定義個size變數,代表輸入數字的size,這裡需要注意的是objs和size含義不同,一定要區分,objs裡面是自定義存放的個數,而size是你設定到List集合中數的個數。
接下來我們來實現get方法,為了方便測試,我們自定義的get方法有2個,而實際的ArrayList中的get方法只有一個,即根據下標index去查詢對應的元素,第一個get方法直接返回當前陣列的長度,第二個可以根據傳進來的index來查詢對應元素。
解釋下第二個get(int index),需要先判斷當前傳入的Index是不是大於陣列總長度,或者小於0,如果是的話直接手動丟擲異常,實際上應該是自定義一個異常,裡面採用列舉定義,然後這裡捕獲,為了簡化就這樣吧。。。如果沒有越界就直接輸出。
add()實現思路:
思考一下,如果定義的objs是10,但是使用者add進來100個數,這時候就會出現問題,很明顯objs存不下來,自然取的話也會是問題,這時候我們考慮讓它自動擴容,在ArrayuList中擴容的倍數其實是原有倍數*3/2再加1,具體為什麼是這樣我們姑且不管(估計和泊松分佈有關,就像Map擴容倍數為0.75),假設現在擴容完畢了,那麼接下來該怎麼處理呢?自然是再定義個新陣列,將之前陣列中的資料拷貝到新陣列中去,但是此刻輸出的時候依舊是原來陣列中的數,所以這個時候就需要新陣列中的數給原來陣列進行輸出,有點繞,舉個例子哈,假如你現在是單身狗(我也是),你自己租一間10多平米的房可以夠住了,但是突然有一天你脫單了,那你和女朋友住在一起的話是不是有點擠(因為才10多平米)。那怎麼辦呢?只能換大點房子住了(新陣列),但是住新房子的還是你們2個人,只是把你們2個人換到了大房子,大家慢慢體會哈。在ArrayList原始碼中是採用了System.arraycopy方法來實現拷貝,我們這裡採用最原始的方式手動實現,下面是實現程式碼以及測試是否可以自動擴容的程式碼:
set() 實現思路:
set方法是將陣列下標的值改變,很容易就能想到set方法需要定義2個引數,一個是index,一個是Object型別的value,接下來更簡單,直接將傳進來的value賦值給對應的index位置。
clear() 實現思路:
clear方法的作用是清除陣列中的所有數,因此我們可以迴圈陣列中的所有值,然後給它們分別賦值為null,別忘記給size設定為0,這時候陣列中已經沒有元素了。
remove() 實現思路:
其實我個人覺得remove才是整個ArrayList最複雜的方法,在真正的ArrayList原始碼中用到了很多很多精巧的設計和演算法,我們首先來考慮下為什麼複雜,比如對移除完的元素需要垃圾回收對吧,什麼時候進行垃圾回收?如何回收?這些都設計到了JVM的知識和更加複雜的演算法,有興趣的話大家可以自行研究,這裡我只是簡單實現了對數字和字串的刪除接下來說下思路。
四、總結
ArrayList原始碼中遠遠比我們這個手寫過程複雜,我們需要學習的是寫JDK原始碼大佬們的思想。
檢視更多內容請關注公眾號: