Java ArrayList是基於數組實現的嗎?有些數組可以存放基本類型,為什麼List不可以?

Right^岸


ArrayList相關的知識點也是java面試中最頻繁出現的點,下面從源碼的角度來分析下Arraylist!

1,ArrayList中的屬性:ArrayList中的屬性主要定義了一個對象數組(Object[]),大小(size),初始容量(DEFAULT_CAPACITY=10)等等,從屬性中就可以知道ArrayList的底層就是一個數組,使用泛型E來存放構造器中傳入的對象類型,當然ArrayList存放的並不是對象本身,而是對象的引用,所以ArrayList不能存放八個基本類型的數據;


2,ArrayList的主要方法:從下面截圖可以看出,ArrayList中的主要方法就是元素的add(增),remove(刪),set(改),get(查),而由這四大類方法自然衍生了獲取大小,擴容,清空,包含等方法!


下面就主要方法進行分析:

1,add方法(add(i),addAll()等類似):



①,先判斷加入元素後的數組大小,如果是小於初始容量則返回初始容量,否則返回+1後的容量值; ②,容量加1,同時跟未加入元素時的數組length比較,如果大於length,則使用grow方法進行擴容;

③, int newCapacity = oldCapacity + (oldCapacity >> 1); >>右移符號,相當於除二,即新容量為老容量的(1+0.5=1.5)倍,再進行判斷是否新容量已經超限(Integer.MAX_VALUE - 8),如果超限,則置為最大容量,否則使用Arrays.copyOf複製得到新數組;

2,remove方法(remove其他方法類似):


①,先判斷是否下標越界,越界拋出異常,否則繼續

②,獲取到相應下標的元素;

③,將下標後面的元素使用System.arraycopy往前移動一位; ④,將遺留出的最後一位置為null,讓GC進行回收,並返回②中獲得的值;

3,get,set方法:比較簡單,就是使用指定下標進行數據替換或者獲取;

記錄幾個ArrayList中碰到的坑 :

1,線程不安全:所有的數據存取都是線程不安全的,所以多線程環境要麼使用Vector,要麼使用CopyOnWriteArrayList;

2,Arraylist是實現了序列化接口的,但使用subList方法返回的是SubList對象,這個對象並沒有序列化,在網絡傳輸中會報錯的;

3,使用remove方法遇到的坑,因為remove方法重載了兩個,remove(int i)和remove(Object o),如果是傳入Integer類型的參數,默認調用第二個,則刪除元素失敗,案例如下:

可以說ArrayList是JAVA開發過程中最常使用的數據結構,底層實現也不難,但是如果不瞭解的話,面試容易被問倒,更多的JAVA技術會一直持續分享的,敬請關注。。。謝謝!


分享到:


相關文章: