天天看點

java.util.Collection源碼分析和深度講解

java.util.Collection源碼分析和深度講解

寫在開頭

  java.util.Collection 作為Java開發最常用的接口之一,我們經常使用,今天我帶大家一起研究一下Collection接口,希望對大家以後的程式設計以及系統設計能有所幫助,本文所研究的jdk版本為jdk1.8.0_131

明确一下幾點:

    •   Collection是接口,其繼承了Iterable接口
    •   Collection屬于單值類型集合,重點子接口List接口和Set接口
java.util.Collection源碼分析和深度講解

Java.util.List接口(有序、不唯一)

   ArraryList

java.util.Collection源碼分析和深度講解

  ArrayList 是一個數組隊列,相當于 動态數組。與Java中的數組相比,它的容量能動态增長。它繼承于AbstractList,實作了List, RandomAccess, Cloneable, java.io.Serializable這些接口。ArrayList是非同步的,效率高但是線程不安全,Collections.sychromiziedList(new ArraryList<>());可以讓那個ArrayList變成線程安全類

    • ArrayList是基于動态數組實作的,在增删時候,需要數組的拷貝複制。
    • ArrayList的預設初始化容量是10,每次擴容時候增加原先容量的一半,也就是變為原來的1.5倍
    • 删除元素時不會減少容量,若希望減少容量則調用trimToSize()
    • 它不是線程安全的。它能存放null值。

   LinkedList

  

java.util.Collection源碼分析和深度講解

  LinkedList是一個雙向循環清單隊列

    • LinkedList 是一個繼承于AbstractSequentialList的雙向連結清單。它也可以被當作堆棧、隊列或雙端隊列進行操作。
    • LinkedList 實作 List 接口,能對它進行隊列操作。
    • LinkedList 實作 Deque 接口,即能将LinkedList當作雙端隊列使用。
    • LinkedList 實作了Cloneable接口,即覆寫了函數clone(),能克隆。
    • LinkedList 實作java.io.Serializable接口,這意味着LinkedList支援序列化,能通過序列化去傳輸。
    • LinkedList 是非同步的。

   Vector

    • 底層是數組,現在已少用,被ArrayList替代,原因有兩個:
    • Vector所有方法都是同步,有性能損失。
    • Vector初始length是10 超過length時 以100%比率增長,相比于ArrayList更多消耗記憶體。
    • 參考資料:https://www.zhihu.com/question/31948523/answer/113357347

  總的來說:查詢多用ArrayList,增删多用LinkedList。

  ArrayList增删慢不是絕對的(在數量大的情況下,會有例外):

    •   如果增加元素一直是使用

      add()

      (增加到末尾)的話,并且不擴容的情況下)
    •   一直删除末尾的元素也是ArrayList要快【不用複制移動位置】
    •   至于如果删除的是中間的位置的話,還是ArrayList要快!

  但一般來說:增删多還是用LinkedList,因為上面的情況是極端的~

Java.util.Set接口(無序、唯一)

                                  |——SortedSet接口——TreeSet實作類

               Set接口——|——HashSet實作類                

                                   |——LinkedHashSet實作類

  hashSet

  hashSet底層基于hashMap實作,如圖

java.util.Collection源碼分析和深度講解

  hashSet中的add()方法,是将對象E放入hashMap中的key的位置,value位置存放的是一個固定的Object,如圖:

java.util.Collection源碼分析和深度講解
java.util.Collection源碼分析和深度講解

  HashSet是無序唯一的,當元素為自定義對象時,兩者的hashCode不同,被認為是不同的元素進而被允許放入HashSet中,但這不符合實際的生産意義,是以需要讓其判定位相等,就要重寫hashCode(),然而重寫HashCode(),會出現重碼的bug,是以需要重寫equals()來解決

  添加元素的時候,如果key(也對應的Set集合的元素)相等,那麼則修改value值。而在Set集合中,value值僅僅是一個Object對象罷了(該對象對Set本身而言是無用的)。

也就是說:Set集合如果添加的元素相同時,是根本沒有插入的(僅修改了一個無用的value值),從源碼(HashMap)中也看出來,==和equals()方法都有使用,具體過程如下

    1.   新元素的hsah是否等于老元素的hash,如果不相等,則元素不同,如果相等,那麼進行第二部比較
    2.   新元素與老元素用“==”進行比較,如果相等,則為同一進制素,若不同則進行第三部比較
    3.   新元素和老元素用equals()方法判定是否相等,如果不等則不是同一進制素,如果相等那麼結果為:兩個元素不是同一個對象,程式想把它們當成同一個對象,是以重寫了equals方法;

  TreeSet

   與HashSet是基于HashMap實作一樣,TreeSet同樣是基于TreeMap實作的。

TreeSet是SortedSet接口的唯一實作類,TreeSet可以確定集合元素處于排序狀态。TreeSet支援兩種排序方式,自然排序 和定制排序,其中自然排序為預設的排序方式。向  TreeSet中加入的應該是同一個類的對象。

  LinkedHashSet 

   LinkedHashSet是HashSet的一個“擴充版本”,HashSet并不管什麼順序,不同的是LinkedHashSet會維護“插入順序”。HashSet内部使用HashMap對象來存儲它的元素,而LinkedHashSet内部使用LinkedHashMap對象來存儲和處理它的元素

原文位址

https://www.cnblogs.com/lsgspace/p/10464757.html