1. 程式人生 > >Set、List、Map的區別與聯絡,及面試重點問題

Set、List、Map的區別與聯絡,及面試重點問題

Set、List、Map的區別

List

  • 1.可以允許重複的物件。

  • 2.可以插入多個null元素。

  • 3.是一個有序容器,保持了每個元素的插入順序,輸出的順序就是插入的順序。

  • 4.常用的實現類有 ArrayList、LinkedList 和 Vector。ArrayList 最為流行,它提供了使用索引的隨意訪問,而 LinkedList 則對於經常需要從 List 中新增或刪除元素的場合更為合適。

Set

  • 1.不允許重複物件
  • 2. 無序容器,你無法保證每個元素的儲存順序,TreeSet通過 Comparator  或者 Comparable 維護了一個排序順序。
  • 3. 只允許一個 null 元素
  • 4.Set 介面最流行的幾個實現類是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基於 HashMap 實現的 HashSet;TreeSet 還實現了 SortedSet 介面,因此 TreeSet 是一個根據其 compare() 和 compareTo() 的定義進行排序的有序容器。

map

  • 1.Map不是collection的子介面或者實現類。Map是一個介面。
  • 2.Map 的 每個 Entry 都持有兩個物件,也就是一個鍵一個值,Map 可能會持有相同的值物件但鍵物件必須是唯一的。
  • 3. TreeMap 也通過 Comparator  或者 Comparable 維護了一個排序順序。
  • 4. Map 裡你可以擁有隨意個 null 值但最多隻能有一個 null 鍵。
  • 5.Map 介面最流行的幾個實現類是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)

那麼什麼場景下使用list,set,map呢?

  1. 如果你經常會使用索引來對容器中的元素進行訪問,那麼 List 是你的正確的選擇。如果你已經知道索引了的話,那麼 List 的實現類比如 ArrayList 可以提供更快速的訪問,如果經常新增刪除元素的,那麼肯定要選擇LinkedList。

  2. 如果你想容器中的元素能夠按照它們插入的次序進行有序儲存,那麼還是 List,因為 List 是一個有序容器,它按照插入順序進行儲存。

  3. 如果你想保證插入元素的唯一性,也就是你不想有重複值的出現,那麼可以選擇一個 Set 的實現類,比如 HashSet、LinkedHashSet 或者 TreeSet。所有 Set 的實現類都遵循了統一約束比如唯一性,而且還提供了額外的特性比如 TreeSet 還是一個 SortedSet,所有儲存於 TreeSet 中的元素可以使用 Java 裡的 Comparator 或者 Comparable 進行排序。LinkedHashSet 也按照元素的插入順序對它們進行儲存。

  4. 如果你以鍵和值的形式進行資料儲存那麼 Map 是你正確的選擇。你可以根據你的後續需要從 Hashtable、HashMap、TreeMap 中進行選擇。

ArrayList和LinkedList區別:

1.ArrayList是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結構。
2.對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標。
3.對於新增和刪除操作add和remove,LinedList比較佔優勢,因為ArrayList要移動資料。

VectorArrayList 區別:

1. Vector的方法都是同步的(Synchronized),是執行緒安全的(thread-safe),而ArrayList的方法不是,由於執行緒的同步必然要影響效能,因此,ArrayList的效能比Vector好。

2.當Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增加50%的大小,這樣,ArrayList就有利於節約記憶體空間。

HashSet和TreeSet的區別:

1.TreeSet 是二叉樹實現的,Treeset中的資料是自動排好序的,不允許放入null值。

2.HashSet 是雜湊表實現的,HashSet中的資料是無序的,可以放入null,但只能放入一個null,兩者中的值都不能重複,就如資料庫中唯一約束。

3.HashSet要求放入的物件必須實現HashCode()方法,放入的物件,是以hashcode碼作為標識的,而具有相同內容的 String物件,hashcode是一樣,所以放入的內容不能重複。但是同一個類的物件可以放入不同的例項 。

HashSet與HashMap的區別:

HashMap HashSet
實現了Map介面 實現Set介面
儲存鍵值對 僅儲存物件
呼叫put()向map中新增元素 呼叫add()方法向Set中新增元素
HashMap使用鍵(Key)計算Hashcode

HashSet使用成員物件來計算hashcode值,

對於兩個物件來說hashcode可能相同,

所以equals()方法用來判斷物件的相等性,

如果兩個物件不同的話,那麼返回false

HashMap相對於HashSet較快,因為它是使用唯一的鍵獲取物件 HashSet較HashMap來說比較慢

TreeSet和TreeMap的關係

與HashSet完全類似,TreeSet裡面絕大部分方法都市直接呼叫TreeMap方法來實現的。

相同點:

TreeMap和TreeSet都是非同步集合,因此他們不能在多執行緒之間共享,不過可以使用方法Collections.synchroinzedMap()來實現同步

執行速度都要比Hash集合慢,他們內部對元素的操作時間複雜度為O(logN),而HashMap/HashSet則為O(1)。

TreeMap和TreeSet都是有序的集合,也就是說他們儲存的值都是拍好序的。

不同點:

  • 最主要的區別就是TreeSet和TreeMap分別實現Set和Map介面
  • TreeSet只儲存一個物件,而TreeMap儲存兩個物件Key和Value(僅僅key物件有序)
  • TreeSet中不能有重複物件,而TreeMap中value可以存在重複物件。
  • TreeMap的底層採用紅黑樹的實現,完成資料有序的插入,排序。

 HashMap和HashTable的區別:

  1. HashMap是非執行緒安全的,Hashtable是執行緒安全的,所以Hashtable重量級一些,因為使用了synchronized關鍵字來保證執行緒安全。
  2. HashMap允許key和value都為null,而Hashtable都不能為null。
  3. Hashtable繼承自 JDK 1.0 的 Dictionary 虛擬類,而HashMap是 JDK 1.2 引進的 Map 介面的一個實現。
  4. Hashtable和HashMap擴容的方法不一樣,Hashtable中陣列預設大小11,擴容方式是 old*2+1。HashMap中陣列的預設大小是16,而且一定是2的指數,增加為原來的2倍。
  5. 兩者通過hash值雜湊到hash表的演算法不一樣,Hashtable是古老的除留餘數法,直接使用Object的hashcode,而後者是強制容量為2的冪,重新根據hashcode計算hash值,在使用hash和(hash表長度 – 1)進行與運算,也等價取膜,但更加高效,取得的位置更加分散,偶數,奇數保證了都會分散到。前者就不能保證。
  6. HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以當有其它執行緒改變了HashMap的結構(增加或者移除元素),將會丟擲ConcurrentModificationException,但迭代器本身的remove()方法移除元素則不會丟擲ConcurrentModificationException異常