Java集合List、Set、Map

集合是 java 基礎中很是重要的一部分,一樣也是 Java 面試中很重要的一個知識點。因此,給王小整理了這篇關於集合的文章。java

一、接口繼承關係以及實現

集合類存放於 Java.util 包中,主要有 3 種:set、list 和 map。面試

  • Collection:Collection 是集合 List、Set、Queue 的最基本的接口
  • Iterator:迭代器,能夠經過迭代器遍歷集合中的數據
  • Map:是映射表的基礎接口

層次關係圖:數組

二、List

Java 的 List 是很是經常使用的數據類型。List 是有序的 Collection。Java List 一共三個實現類:分別是 ArrayList、Vector 和 LinkedList。安全

2.一、ArrayList

ArrayList 是最經常使用的 List 實現類,內部是經過數組實現的,它容許對元素進行快速隨機訪問。數組的缺點是每一個元素之間不能有間隔,當數組大小不知足時須要增長存儲能力,就要將已經有數組的數據複製到新的存儲空間中。當從 ArrayList 的中間位置插入或者刪除元素時,須要對數組進行復制、移動、代價比較高。所以,它適合隨機查找和遍歷,不適合插入和刪除。微信

2.二、Vector

Vector 與 ArrayList 同樣,也是經過數組實現的,不一樣的是它支持線程的同步,即某一時刻只有一個線程可以寫 Vector,避免多線程同時寫而引發的不一致性,但實現同步須要很高的花費,所以,訪問它比訪問 ArrayList 慢。多線程

LinkedList 是用鏈表結構存儲數據的,很適合數據的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了 List 接口中沒有定義的方法,專門用於操做表頭和表尾元素,能夠看成堆棧、隊列和雙向隊列使用。併發

三、Set

Set 注重獨一無二的性質,該體系集合用於存儲無序(存入和取出的順序不必定相同)元素,值不能重複。對象的相等性本質是對象 hashCode 值(java 是依據對象的內存地址計算出的此序號)判斷的,若是想要讓兩個不一樣的對象視爲相等的,就必須覆蓋 Object 的 hashCode 方法和 equals 方法。java Set 一共三個實現類:分別是 HashSet、TreeSet 和 LinkHashSet。app

3.一、HashSet

哈希表邊存放的是哈希值。HashSet 存儲元素的順序並非按照存入時的順序(和 List 顯然不一樣) 而是按照哈希值來存的因此取數據也是按照哈希值取得。元素的哈希值是經過元素的hashcode 方法來獲取的, HashSet 首先判斷兩個元素的哈希值,若是哈希值同樣,接着會比較equals 方法 若是 equls 結果爲 true ,HashSet 就視爲同一個元素。若是 equals 爲 false 就不是同一個元素。函數

哈希值相同 equals 爲 false 的元素是怎麼存儲呢,就是在一樣的哈希值下順延(能夠認爲哈希值相同的元素放在一個哈希桶中)。也就是哈希同樣的存一列。如圖 1 表示 hashCode 值不相同的狀況;圖 2 表示 hashCode 值相同,但 equals 不相同的狀況。spa

HashSet 經過 hashCode 值來肯定元素在內存中的位置。一個 hashCode 位置上能夠存放多個元素。

3.二、TreeSet
  1. TreeSet() 是使用二叉樹的原理對新 add() 的對象按照指定的順序排序(升序、降序),每增長一個對象都會進行排序,將對象插入的二叉樹指定的位置。
  2. Integer 和 String 對象均可以進行默認的 TreeSet 排序,而自定義類的對象是不能夠的,本身定義的類必須實現 Comparable 接口,而且覆寫相應的 compareTo()函數,才能夠正常使用。
  3. 在覆寫 compare()函數時,要返回相應的值才能使 TreeSet 按照必定的規則來排序。
  4. 比較此對象與指定對象的順序。若是該對象小於、等於或大於指定對象,則分別返回負整數、零或正整數。
3.三、LinkHashSet

對於 LinkedHashSet 而言,它繼承與 HashSet、又基於 LinkedHashMap 來實現的。
LinkedHashSet 底層使用 LinkedHashMap 來保存全部元素,它繼承與 HashSet,其全部的方法操做上又與 HashSet 相同,所以 LinkedHashSet 的實現上很是簡單,只提供了四個構造方法,並經過傳遞一個標識參數,調用父類的構造器,底層構造一個 LinkedHashMap 來實現,在相關操做上與父類 HashSet 的操做相同,直接調用父類 HashSet 的方法便可。

四、Map

4.一、HashMap

HashMap 根據鍵的 hashCode 值存儲數據,大多數狀況下能夠直接定位到它的值,於是具備很快的訪問速度,但遍歷順序倒是不肯定的。 HashMap 最多隻容許一條記錄的鍵爲 null,容許多條記錄的值爲 null。HashMap 非線程安全,即任一時刻能夠有多個線程同時寫 HashMap,可能會致使數據的不一致。若是須要知足線程安全,能夠用 Collections 的 synchronizedMap 方法使HashMap 具備線程安全的能力,或者使用 ConcurrentHashMap。

4.二、HashTable

Hashtable 是遺留類,不少映射的經常使用功能與 HashMap 相似,不一樣的是它承自 Dictionary 類,
而且是線程安全的,任一時間只有一個線程能寫 Hashtable,併發性不如 ConcurrentHashMap,
由於 ConcurrentHashMap 引入了分段鎖。Hashtable 不建議在新代碼中使用,不須要線程安全
的場合能夠用 HashMap 替換,須要線程安全的場合能夠用 ConcurrentHashMap 替換。

4.三、TreeMap

TreeMap 實現 SortedMap 接口,可以把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,
也能夠指定排序的比較器,當用 Iterator 遍歷 TreeMap 時,獲得的記錄是排過序的。
若是使用排序的映射,建議使用 TreeMap。

4.四、LinkHashMap

LinkedHashMap 是 HashMap 的一個子類,保存了記錄的插入順序,在用 Iterator 遍歷LinkedHashMap 時,先獲得的記錄確定是先插入的,也能夠在構造時帶參數,按照訪問次序


五、總結

一、三者之間的區別

  • list 有序、能夠重複,有三個實現類,ArrayList、linkedList、Vector
  • set 無序、不可重複,有兩個實現類,HashSet、LinkedhashSet
  • map 鍵不能夠重複、值能夠重複,有三個實現類,HashMap、HashTable、LinkedHashMap

二、List 三個子類的區別

  • ArrayList:底層使用object[]數組實現,內存地址都是連續的便於索引,查詢快;在新增的時候須要申請一塊連續的內存空間,因此增刪比較慢。
  • LinkedList: 底層是基於鏈表實現,鏈表內存是散亂的,在儲存自身內存地址的
    同時,還儲存着下一個元素的內存地址,因此查詢慢,增刪快。
  • Vector:底層數組實現,因爲全部的方法都是採用synchronize,線程安全,效率慢。

三、map 三個子類的區別

  • HashMap:基於hash表的Map接口實現,非線程安全,支持鍵null、值null
  • HashTab:線程安全,不支持鍵null,值null
  • LinkedHashMap:持兩種排序:插入順序、訪問順序。前者是指按照插入時的順序排序,後者是指按照最舊使用到最近使用的順序

四、set 兩個子類的區別

  • HashSet:底層由HashMap實現
  • LinkedHashSet:LinkedHashSet 繼承自 HashSet,源碼更少、更簡單,惟一的區別是 LinkedHashSet 內部使用的是 LinkHashMap。這樣作的意義或者好處就是 LinkedHashSet 中的元素順序是能夠保證的,也就是說遍歷序和插入序是一致的

若是文章有錯的地方歡迎指正,你們互相留言交流。習慣在微信看技術文章,想要獲取更多的Java資源的同窗,能夠關注微信公衆號:niceyoo

相關文章
相關標籤/搜索