1. 程式人生 > >java基礎複習---集合之List--11.16

java基礎複習---集合之List--11.16

Java容器類類庫的用途是儲存物件,並將其劃分為兩個不同的概念。

1)、Collection。一個獨立元素的序列,這些元素都服從一條或多條規則。List必須按照插入的順序儲存元素。而Set不能有重複的元素。Queue按照排隊規則來確定物件產生的順序(通常與物件插入的順序相同)

2)、Map。一組成對的“鍵值對”物件,允許你通過鍵來查詢值。ArrayList允許你通過數字來查詢值,因此在某種意義上,它將數字與物件關聯在了一起。對映表允許我們使用另一個物件來查詢某一個物件,它也被稱為“關聯陣列”,因為它將某些物件與另外一些物件關聯在了一起;或者被稱為“字典”,因為你可以通過使用鍵物件來查詢值,就像在字典中使用單詞來定義一樣。

一、List

List可以將元素維護在特定的序列中。List介面在Collection的基礎上添加了大量的方法,使得可以在List的中間插入和移除元素。

有兩種基本型別的List:ArrayList和LinkedList。

ArrayList實現了隨機訪問的介面(RandomAccess),是基於資料實現的list,有著陣列的特性,適合讀取資料,但是對於增刪改操作效率較LinkedList低。

Linkedlist實現了Queue的介面,是基於連結串列實現的介面,有著連結串列的特性,增刪改操作快,但是查資料的效率低於ArrayList。

如果通俗的講,如果增刪改操作使用較少的話,是為了檢視資料,建議使用ArrayList,如果會出現大量增刪操作的話建議使用LinkedList。

下面通過程式碼來看一下常用的ArrayList用法吧。

在這裡呢,要說明一下indexOf()  在這裡例子中出現的效果,能出現按下標排序的,是因為集合中元素不重複。還有一個,我輸出時為什麼要用list[index] 呢?是因為對於Arraylist來說,它的底層實現是通過陣列來實現的。

通過它的構造方法可以看出來,是一個Object[]來作為實現的,也就是為什麼我們可以通過下標來取值的原因。在這裡,我們看一下set和add,remove的原始碼吧。

新增一個元素,在原始碼中使用了System.arraycopy()方法,實現對陣列的擴容。

set()方法就是下標為index處元素重新賦值,並返回舊的值。rangeCheck只是檢查下標是否合法的。

對於remove方法來說,底層實現也是使用了System.arraycopy方法。

對於ArrayList的方法在LinkedList中也同樣適用,在這裡方法作用不看了,來說明一下LinkedList的增刪改為什麼比ArrayList快吧。

LinkedList是雙向連結串列結構,由節點構成,而一個節點包括上一節點引用,當前節點元素,下一節點引用三個資訊,這個是首先要知道的

先來看一下add方法

在這裡,對於直接新增的元素,說明新增在最後,使用了linkLast方法,對於連結串列的最後一個節點是有記錄的,

頭結點和尾節點。當直接新增最後一個元素的時候呢,就是將要新增的節點的prev也就是上一個節點引用指向,而next為null(對於雙向連結串列結構來說,first節點的prev為null,last節點的next為null)。那當在中間新增節點時怎麼做呢?這裡看到linkedBefore傳遞過去兩個引數,一個要新增的元素,一個是要新增下標處的節點資訊。然後呢?

使用當前下標處元素(succ)的prev引用當做要新增節點的prev,而要新增元素的next就變成了succ,succ的prev引用就變成了新新增元素的節點資訊。當然,對於你要新增的位置為頭元素時,則需要記錄first為新新增節點資訊。對於這樣的新增是比System.arraycopy()效率要好的。

看完add,來看下remove怎麼實現的

他的刪除是這樣的,找到下標處的節點(x),然後將他的前一個節點(prev)的next指向x的下一節點引用,同時將x.prev賦值為null;將他的下一個節點資訊(next)的prev指向x的上一個節點引用,同時將x.next賦值為null。然後將x.item置為null,這樣這個節點資訊就沒用了。也就是節點刪除了。如果要刪除的元素是頭節點或者是尾節點的話,那麼就將下一個元素或上一個元素的prev或next置為null咯。對於他的查詢效率不如ArrayList來說,我們看一下他的get方法實現:

這裡採取了一種查詢優化吧也算,就是當index小於當前節點數大小的一半時,就遍歷index次然後找到節點資訊,在返回節點處元素。當不小於一辦時,就遍歷size-index-1次找到這個元素的下一個節點,然後返回它的上一節點處元素。比陣列取值麻煩。

對於集合中的map以及set來說,準備複習執行緒之後再來說。