JAVA 面試高頻提問知識點之:SET、LIST 和 MAP 的區別

  首先,Set 、List 和 Map 是 Java 容器框架的三個最重要的接口,Set、List 和 Map 之間的區別是 Java 容器面試時最經常提問的問題之一。有時這一問題被問作是什麼時候使用 List、Set 和 Map。很明顯,面試官想知道的是你是否熟悉 Java 容器框架的基礎知識。要想明確何時使用 List、Set 或者 Map,你首先需要去了解這些接口是什麼、它們提供了什麼功能。Java 裡的 List 提供了一個有序且有索引的容器,它允許重複值的出現。Set 提供了一個無序的唯一對象的容器,也就是說,Set 不允許重複值,而 Map 提供的則是一個基於鍵值對以及哈希的數據結構。List、Set 和 Map 這三個都是 Java 裡的接口,在容器 API 裡都有很多現成的實現。ArrayList 和 LinkedList 是兩個最常使用的 List 實現,LinkedHashSet、TreeSet 和 HashSet 則是最常用的 Set 實現。本文我們將具體闡述 Java 語言中 Map、Set 和 Set 的區別並學會什麼時候使用 List、Set 或者 Map。

Set vs List vs Map

前邊提到了,Set、List 和 Map 都是接口,它們定義了核心約束,比如一個 Set 約束說明了它不能包含重複值。下邊我們就不同的指標對 List、Set 和 Map 進行對比。

重複對象

Java 裡 List 和 Set 接口的最主要的區別就在於 List 允許有重複對象而 Set 不允許重複對象。所有的 Set 實現都必須遵循這一約束。Map 的 每個 Entry 都持有兩個對象,也就是一個鍵一個值,Map 可能會持有相同的值對象但鍵對象必須是唯一的。更多關於 List 和 Set 數據結構的區別請參考這裡。

排序

List 和 Set 接口的另一個關鍵區別是 List 是一個有序容器,List 保持了每個元素的插入順序。Set 是一無序容器,你無法保證每個元素的存儲順序。但是某些 Set 實現比如 LinkedHashSet 還是保持了每個元素的插入順序。此外 SortedSet 和 SortedMap 比如 TreeSet 和 TreeMap 也通過 Comparator 或者 Comparable 維護了一個排序順序。

空元素

List 允許空元素,你可以在一個 List 裡同時擁有很多 null 對象 —— 因為它還允許重複元素。由於不允許重複元素的限制 Set 最多隻允許一個 null 元素,而在 Map 裡你可以擁有隨意個 null 值但最多隻能有一個 null 鍵。值得注意的是 Hashtable 既不允許 null 鍵也不允許 null 值但 HashMap 允許任意數量的 null 值和最多一個 null 鍵。這也是兩個最流行的 Map 接口的實現 HashMap 和 Hashtable 之間最主要的區別。

流行實現

Java 中 List 接口最流行的幾個實現類是 ArrayList、LinkedList 和 Vector。ArrayList 最為流行,它提供了使用索引的隨意訪問,而 LinkedList 則對於經常需要從 List 中添加或刪除元素的場合更為合適。Vector 是 ArrayList 的一個提供了同步功能的副本(功能上這樣講,但內部實現不是基於 ArrayList 實現)。另一方面,Set 接口最流行的幾個實現類是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基於 HashMap 實現的 HashSet,更多細節參考《Java HashSet 的內部實現機制》。HashSet 也不能提供任何排序保證,但 LinkedHashSet 卻除了提供 Set 接口的唯一性之外還提供了元素的有序性。第三個 Set 實現 TreeSet 還實現了 SortedSet 接口,因此 TreeSet 是一個根據其 compare() 和 compareTo() 的定義進行排序的有序容器。最後一個,Map 接口最流行的幾個實現類是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。第一個,HashMap 是 Map 接口的一個非同步的通用實現,Hashtable 是 HashMap 的一個提供了同步功能的副本(功能上這樣講,但內部實現不是基於 ArrayList 實現),HashMap 和 Hashtable 都不能像 LinkedHashMap 那樣做任何排序保證。類似於 TreeSet,TreeMap 也是一個有序的數據結構,它按照鍵的值進行升序排列。

Difference between Set, List and Map in Java

Java 裡什麼時候使用 List、Set 和 Map?

基於以上我們對 Set、List 和 Map 的理解,現在我們可以決定什麼時候使用 List、Set 還是 Map 了。

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

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

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

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

Java Collection framework Map Set and List

Java 裡 Set、List 和 Map 之間的區別就這些。這三個都是 Java 容器框架裡最基本的接口,作為一名 Java 開發者應該知道它們之間的區別特徵並且能夠鑑於指定場景選取使用合適的容器。最好還能夠記住它們實現類之間的區別,比如,什麼時候使用 ArrayList 還是 LinkedList,HashMap vs Hashtable 以及什麼時候使用 Vector 還是 ArrayList 等等。Java 的容器 API 很大,很難對其每一塊知識點都能進行把握,但是如果連最基本的 Set、List 和 Map 之間的區別都回答不上來的話那就說不過去了。

JAVA 面試高頻提問知識點之:SET、LIST 和 MAP 的區別


分享到:


相關文章: