
大家好,今天我們介紹一下java中常用的集合類型。
首先,我們先看一下java中集合類型的結構。

以上是集合的繼承關系圖,通常我們使用的比較多的是 Set , List , Map以及其衍生的子類和接口實現類。
首先給大家介紹一下List,List本身是一個接口類,它向它的實現類定義了一系列的接口函數。
在List類后跟了一個標記,表示對于List來說,是可以指定類型的,比如List,代表list保存的數據類型為String字符串,又比如List,代表list保存的數據類型為封裝int

他代表的是有序的,可重復的一個集合體,為了研究他的具體邏輯,我們從ArrayList的源碼開始對應List接口所規范的接口函數。
1.add(E e);
add函數提供了向ArrayList對象添加一個數據的功能,具體源碼如下

可以看到ArrayList類實現了List接口中的add函數,我們來看看他是如何做的。
首先源碼462行中,調用了函數ensureCapacityInternal,這個函數的主要作用是用于判斷當前集合內保存數據的數組(what?)的長度是否滿足繼續添加,如果不滿足的話就需要進行擴容,具體實現代碼如下


我們發現,ArrayList對象做add操作時似乎是將數據保存在了數組中,向上翻閱源碼

原來ArrayList對象對于數據的保存是確實是放在了數組里,那么從這里我們至少可以了解到,對于ArrayList來說,最多保存的數據量也就是int數字的最大值。而由于保存的內容是放在數組里的,于是,對于ArrayList,保存的數據是有順序性的(數組用標識來表示順序)。
接著看源碼的463行,add函數將傳入的參數加入到了數組中,放入的位置是size++。那么size又代表什么呢,我們繼續查看源碼

上面的注釋已經很明確的告訴我們,size代表的是當前的arraylist對象的長度,由于int類型的默認值為0,所以,當我們第一次調用add函數,執行的代碼實際上是
elementData[0] = e;
由于執行了size++,所以,當這一次add操作完成時,size的值由0 增長 為了1,那么下一次再執行add操作時,傳入的參數就放到了數組的標識1的位置。
2.size();

根據上面的分析,我們很容易就可以知道,這個函數得到的結果是當前ArrayList對象中數據數組所保存的數據數量(不是數組長度)
了解了這些內容,那么其他的函數就比較好理解了。
3.isEmpty()

判斷當前對象的數據量是否是0
4.indexOf(Object o)

通過正向遍歷,獲得指定值第一次出現的標識值
5.lastIndexOf(Object o)

通過逆向遍歷,獲得指定值最后一次出現的標識值
6.contains(Object o)

調用indexof函數確定指定的值時否存在于當前數組中
7.get(int index)


rangeCheck函數用于確定傳入的標識是在數組的允許標識范圍內,如果沒有滿足,則會拋出異常,對于異常,在后續章節會為大家介紹。接著,調用elementData函數返回數組中指定標識的數據
8.remove(int index) / remove(Object o)

remove函數刪除指定標識的數據/remove函數刪除指定內容的數據
remove函數稍微復雜一些,首先驗證了標識的正確性,接著將指定標識位置的數據暫存在oldValue變量中,接著通過系統提供的arraycopy函數將當前數組中從標識的位置開始,一直都尾部的數據進行重新覆蓋,接著,size自減,并將數組的最后一位設置為null。
上圖為各位演示ArrayList的使用示例

運行結果為

ps:對于源碼中的一些函數如果不能理解,可以嘗試自己去找找資料,或者給 進擊留言,有時間的時候會給大家回復的哈。
通過add和remove函數,我們了解到,ArrayList本身實現基于數組,而又由于數組本身的特性(定義長度后不可更改長度,只能重新聲明),ArrayList在增加,刪除時,系統資源開銷會比較大,所以,如果在以后有需要頻繁的增刪操作的集合結構,應該盡量避免使用ArrayList。
以上就是ArrayList類中一些常用的函數,除了這些之外,還有很多沒有介紹到的函數,大家可以自己去了解一下。