盤點Java中List、Set、Map實現類以及他們之間的區別

沒有進行擴展,方便複習。需要更詳細的,可以訪問我的博客查看其它文章

在這裏插入圖片描述

一、List

存放是有序的,允許存放重複元素

1.1 ArrayList

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

1.2 LinkedList

LinkedList是用雙向鏈表結構存儲數據的,很適合數據的動態插入和刪除隨機訪問和遍歷速度比較 慢。另外,他實現了Deque接口,可以用於操作表頭和表尾元素,可以當作堆 棧、隊列和雙向隊列使用。

1.3 Vector

Vector與ArrayList一樣,也是通過數組實現的,不同的是它支持線程的同步,即某一時刻只有一 個線程能夠寫 Vector,避免多線程同時寫而引起的不一致性,但實現同步需要很高的花費,因此, 訪問它比訪問ArrayList慢

二、Set

Set是沒有順序,且不可重複的。判斷是否是相同對象是通過對比對象hashCode值(java是依據對象的內存地址計算出的此序號)判斷 的,如果想要讓兩個不同的對象視爲相等的,就必須覆蓋Object的hashCode方法和equals方法。

在這裏插入圖片描述

2.1 HashSet(哈希表)

**Set不允許重複,底層是HashMap,無容量限制,是非線程安全的。**雖然底層是HashMap但不存儲鍵值對,值存儲對象。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-k950Ow01-1590396561161)(https://gitee.com/hofe/graph/raw/master/img/20200525121559.png)]

HashSet根據元素的哈希值來決定存儲在哪個位置,哈希值相同的使用equals判斷是否是同一元素,是的話插入操作失敗,不是的話就在相同的哈希值下順延

HashSet存儲元素的順序並不是按照存入時的順序(和List顯然不 同) 而是按照哈希值來存的所以取數據也是按照哈希值取得。

元素的哈希值是通過元素的 hashcode方法來獲取的, HashSet首先判斷兩個元素的哈希值,如果哈希值一樣,接着會比較 equals方法 如果 equls結果爲true ,HashSet就視爲同一個元素。如果equals 爲false就不是 同一個元素。 哈希值相同equals爲false的元素在同樣的哈希值下順延.

2.2 TreeSet

基於TreeMap實現,支持排序,是非線程安全的

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

2.3 LinkHashSet

LinkHashSet(HashSet+LinkHashMap),繼承自HashSet,底層是LinkedHashMap。這樣做的好處是LinkHashSet中的元素順序是可以保證的,也就是遍歷序和插入序是一樣的。
對於 LinkedHashSet 而言,它繼承於 HashSet、又基於 LinkedHashMap 來實現的。 LinkedHashSet 底層使用 LinkedHashMap(有序) 來保存所有元素,它繼承與 HashSet,其所有的方法 操作上又與HashSet相同,因此LinkedHashSet 的實現上非常簡單,只提供了四個構造方法,並 通過傳遞一個標識參數,調用父類的構造器,底層構造一個 LinkedHashMap 來實現,在相關操 作上與父類HashSet的操作相同,直接調用父類HashSet的方法即可

三、Map

在這裏插入圖片描述

3.1 HashMap

1.底層是數組+鏈表/紅黑樹

2.無序鍵值對集合,根據鍵的hashCode值存儲數據,大多數情況下可以直接定位到它的值,因而具有很快 的訪問速度。

3.HashMap多隻允許一條記錄的鍵爲null,允許多條記 錄的值爲 null。

4.HashMap 非線程安全,如果需要滿足線程安全,可以用 Collections 的 synchronizedMap 方法使 HashMap 具有線程安全的能力,或者使用 ConcurrentHashMap。

3.2 Hashtable

Hashtable 是遺留類,很多映射的常用功能與 HashMap 類似,不同的是它承自 Dictionary 類實現Map接口 並且是線程安全的,所有的讀寫等操作都進行了鎖(synchronized)保護,任一時間只有一個線程能寫 Hashtable,併發性不如 ConcurrentHashMap, 因爲 ConcurrentHashMap 引入了分段鎖。Hashtable 不建議在新代碼中使用,不需要線程安全 的場合可以用HashMap替換,需要線程安全的場合可以用ConcurrentHashMap替換

3.3 TreeMap

TreeMap 實現 SortedMap 接口,能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序, 也可以指定排序的比較器,當用Iterator遍歷TreeMap時,得到的記錄是排過序的。
如果使用排序的映射,建議使用TreeMap。
在使用 TreeMap 時,key 必須實現 Comparable 接口或者在構造 TreeMap 傳入自定義的 Comparator,否則會在運行時拋出java.lang.ClassCastException類型的異常。

3.4 LinkedHashMap

LinkedHashMap 是 HashMap 的一個子類,底層結構和HashMap一樣,但通過雙向鏈表保存了記錄的插入順序,在用 Iterator 遍歷 LinkedHashMap時,先得到的記錄肯定是先插入的,也可以在構造時帶參數,按照訪問次序排序。

注:TreeMap是按照hashcode進行排序的,LinkedHashMap是根據插入順序進行排序

四、面試題

4.1 list實現類之間的區別

對於需要快速插入、刪除元素的場景,應該使用LinkedList

對於需要快速隨機訪問元素,應該使用ArrayList

對於單線程環境,應該使用非同步的類如ArrayList

對於多線程環境,應該使用同步的類如Vector

4.2 ArrayList和LinkedList的區別?

①ArrayList和LinkedList,一個基於數組實現,一個基於鏈表實現
前者是數組隊列,相當於動態數組;後者爲雙向鏈表結構,也可當作堆棧、隊列、雙端隊列
②當隨機訪問List時(get和set操作),ArrayList比LinkedList的效率更高,因爲LinkedList是線性的數據存儲方式,所以需要移動指針從前往後依次查找。
③當對數據進行增加和刪除的操作時(add和remove操作),LinkedList比ArrayList的效率更高,因爲ArrayList是數組,所以在其中進行增刪操作時,會對操作點之後所有數據的下標索引造成影響,需要進行數據的移動。
④內存空間佔用來看,ArrayList的空間浪費體現在會預留一定的容量空間,而LinkedList中存儲的每個元素都需要存放前驅和後繼的指針,空間佔用會比ArrayList中每個元素的多
⑤ArrayList和LinkedList都是線程不安全

場景:
鏈表,插入刪除快,查找修改慢。 適用於頻繁增刪的場景。
數組,查找快,插入刪除慢。 適用於頻繁查找和修改的場景。

4.3 ArrayList和Vector的區別?

1.ArrayList是線程不安全的,Vector是線程安全的

2.在不需要保證線程安全時應使用ArrayList,因爲Vector在同步操作上會消耗大量時間

4.4 HashMap與HashTable區別

1.HashMap沒有對讀寫等操作進行鎖保護,所以是線程不安全的,在多線程場景下會出現數據不一致的問題。而HashTable是同步的,所有的讀寫等操作都進行了鎖(synchronized)保護,在多線程環境下沒有安全問題。但是鎖保護也是有代價的,會對讀寫的效率產生較大影響

2.HashMap允許鍵和值是null,而Hashtable不允許鍵或者值是null

3.HashMap的迭代器(Iterator)是fail-fast迭代器,但是Hashtable的迭代器(enumerator)不是fail-fast的。如果有其它線程對HashMap進行的添加/刪除元素,將會拋出ConcurrentModificationException,但迭代器本身的remove方法移除元素則不會拋出異常。

4.5 Collection 和 Collections的區別?

Collection是集合類的上級接口,繼承於他的接口主要有Set 和List.
Collections是針對集合類的一個輔助類,他提供一系列靜態方法實現對各種集合的搜索、排序、線程安全化等操作

4.6 Collection集合接口和Map接口有什麼關係?

沒有直接關係,但是一些子類會有依賴,Collection是最基本的集合接口,聲明瞭適用於JAVA集合(只包括Set和List)的通用方法。Map接口並不是Collection接口的子接口,但是它仍然被看作是Collection框架的一部分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章