簡體   English   中英

我應該使用哪個 Java 集合?

[英]Which Java Collection should I use?

在這個問題中, 如何在 C++11 中有效地選擇標准庫容器? 是選擇 C++ 集合時使用的方便流程圖。

我認為對於不確定應該使用哪個集合的人來說,這是一個有用的資源,所以我試圖為 Java 找到一個類似的流程圖,但沒有找到。

有哪些資源和“備忘單”可以幫助人們在 Java 編程時選擇正確的 Collection? 人們如何知道他們應該使用哪些 List、Set 和 Map 實現?

由於找不到類似的流程圖,我決定自己制作一個。

此流程圖並未嘗試涵蓋諸如同步訪問、線程安全等或遺留集合之類的內容,但它確實涵蓋了 3 個標准Set 、3 個標准Map和 2 個標准List

在此處輸入圖片說明

此圖像是為此答案創建的,並根據知識共享署名 4.0 國際許可協議獲得許可。 最簡單的歸因是鏈接到這個問題或這個答案。

其他資源

可能最有用的其他參考資料是 oracle 文檔中描述每個Collection的以下頁面。

HashSet 與 TreeSet

這里有關於何時使用HashSetTreeSet的詳細討論: Hashset vs Treeset

ArrayList 與 LinkedList

詳細討論: 何時使用 LinkedList 而不是 ArrayList?

主要非並發、非同步集合的總結

Collection :一個接口,表示一個無序的“袋子”項目,稱為“元素”。 “下一個”元素未定義(隨機)。

  • Set :表示沒有重復的Collection的接口。
    • HashSet :由Hashtable支持的Set 當排序不重要時,最快和最小的內存使用量。
    • LinkedHashSet :一個HashSet ,添加了一個鏈接列表以按插入順序關聯元素。 “下一個”元素是下一個最近插入的元素。
    • TreeSet :一個Set ,其中元素由Comparator 排序(通常是自然排序)。 最慢和最大的內存使用量,但對於基於比較器的排序是必需的。
    • EnumSet :為單個枚舉類型定制的極其快速和高效的Set
  • List :表示一個Collection的接口,它的元素是有序的,每個元素都有一個數字索引來表示它的位置,其中 0 是第一個元素, (length - 1)是最后一個元素。
    • ArrayList :由數組支持的List ,其中數組的長度(稱為“容量”)至少與元素數量(列表的“大小”)一樣大。 當大小超過容量時(當添加第(capacity + 1)-th元素時),將使用(new length * 1.5)的新容量重新創建數組——這種重新創建速度很快,因為它使用System.arrayCopy() 刪除和插入/添加元素需要將所有相鄰元素(向右)移入或移出該空間。 訪問任何元素都很快,因為它只需要計算(element-zero-address + desired-index * element-size)即可找到它的位置。 在大多數情況下ArrayList優於LinkedList
    • LinkedList :由一組對象支持的List ,每個對象都鏈接到其“上一個”和“下一個”鄰居。 LinkedList也是QueueDeque 訪問元素從第一個或最后一個元素開始,並遍歷直到達到所需的索引。 插入和刪除,一旦通過遍歷達到所需的索引,只需重新映射直接相鄰鏈接以指向新元素或繞過現在刪除的元素即可。
  • Map :表示Collection的接口,其中每個元素都有一個標識“鍵”——每個元素都是一個鍵值對。
    • HashMap :鍵是無序的Map ,並由Hashtable支持。
    • LinkedhashMap :鍵按插入順序排列
    • TreeMap :一個Map ,其中鍵由Comparator排序(通常是自然排序)。
  • Queue :表示Collection的接口,其中元素通常添加到一端,然后從另一端刪除(FIFO:先進先出)。
  • Stack :表示Collection的接口,其中元素通常從同一端添加(推送)和刪除(彈出)(LIFO:后進先出)。
  • Deque :“雙端隊列”的Deque ,通常發音為“deck”。 一個通常只添加到兩端(而不是中間)和從中讀取的鏈表。

基本集合圖:

圖表

將元素插入與ArrayListLinkedList

圖表

更簡單的圖片在這里。 有意簡化!

  1. 集合是任何保存稱為“元素”(相同類型)的數據的東西。 沒有更具體的假設。

  2. 列表是數據的索引集合,其中每個元素都有一個索引。 類似於數組的東西,但更靈活。

    列表中的數據保持插入順序。

    典型操作:獲取第 n 個元素。

  3. Set是一個元素包,每個元素只有一次(使用它們的equals()方法區分元素。

    存儲集中的數據主要是為了知道那里有什么數據。

    典型操作:判斷一個元素是否存在於列表中。

  4. Map類似於 List,但不是通過整數索引訪問元素,而是通過它們的key訪問它們,它是任何對象。 就像 PHP 中的數組 :)

    Map 中的數據可以通過它們的鍵進行搜索。

    典型操作:通過其 ID 獲取元素(其中 ID 是任何類型,而不僅僅是像 List 那樣的int )。

差異

  • Set vs. Map:在 Set 中你可以自己搜索數據,而在 Map 中則是通過他們的 key

    NB 標准庫 Sets 確實是這樣實現的:一個映射,其中鍵是 Set 元素本身,並帶有一個虛擬值。

  • List vs. Map:在 List 中,您可以通過它們的int索引(在 List 中的位置)訪問元素,而在 Map 中通過它們的鍵訪問任何類型的 os(通常:ID)

  • List vs. Set:在 List 中,元素受它們的位置約束並且可以重復,而在 Set 中元素只是“存在”(或不存在)並且是唯一的(在equals()compareTo()的意義上compareTo()對於SortedSet )

這很簡單:如果您需要存儲帶有映射到它們的鍵的值,請使用 Map 接口,否則使用 List 存儲可能重復的值,如果您不想在集合中使用重復的值,最后使用 Set 接口。

這是完整的解釋http://javatutorial.net/choose-the-right-java-collection ,包括流程圖等

地圖

如果選擇Map ,我制作了這個表格,總結了與 Java 11 捆綁在一起的十個實現中每一個的特性。

Java 11 中的地圖實現表,比較它們的特性

公共集合, 公共集合在此處輸入圖片說明

我應該使用哪個Java Collection?

這取決於您要解決的問題或您有哪些要求。

例子 :

  1. 您希望在存儲元素時對元素進行排序嗎? HashSet的
  2. 你想要(Key,Value)對存儲嗎? HashMap中
  3. 您是否希望保留插入時元素的順序? ArrayList,LinkedList
  4. 您想要對(鍵,值)對中的鍵進行排序嗎? - 強文
  5. 你想實現一個堆棧來解決你的問題嗎? - 堆疊
  6. 您想要FIFO(先進先出)訪問嗎? - 隊列
  7. 您是否只想存儲UNIQUE元素? - 哈希集
  8. 你想在存儲(Key,Value)時允許密鑰為“Null”嗎? - HashMap
  9. 你想要(Key,Value)對沒有NULL值嗎? 哈希表

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM