2010-09-12 91 views
43

爲什麼某些集合數據結構不能保持插入順序?與維持插入順序相比,取得的特殊成就是什麼? 如果我們不維護訂單,我們會獲得一些東西嗎?維護插入順序的Java集合

+1

例如,爲什麼'java.util.HashSet'需要維護插入順序? – 2010-09-12 08:09:26

+0

不,我要求..我們在維持秩序時做了什麼事情。我們是否會得到一些東西,如果我們不維護訂單 – JavaUser 2010-09-12 08:11:28

+0

例如:LinkedList。想想看,將它插入/插入鏈表比將它插入中間不是更容易嗎? – st0le 2010-09-12 09:47:11

回答

70

表現。如果您想要原始廣告訂單,則會有LinkedXXX類,它們按廣告訂單維護額外的鏈接列表。大部分時間你不關心,所以你使用HashXXX,或者你想要一個自然順序,所以你使用TreeXXX。在這兩種情況下,爲什麼要支付鏈表的額外費用?

+7

'ArrayList'在哪裏適合答案? – ADTC 2014-09-26 04:42:07

+0

@ADTC它不適合答案。 – EJP 2015-03-20 06:32:48

+0

好吧,ArrayList維護數組後臺的插入順序,但是我認爲性能比LinkedXXX類更糟? – ADTC 2015-03-20 12:50:38

2

取決於你需要什麼實施才能做好。插入順序通常不是很有意思,所以不需要維護它,所以您可以重新排列以獲得更好的性能。

對於地圖,它通常是使用的HashMap和TreeMap。通過使用散列碼,條目可以放在一個小組中,易於搜索.ShitMap以較慢的搜索爲代價維護插入條目的排序順序,但比HashMap更容易排序。

2

當您使用HashSet(或HashMap)數據存儲在基於您的對象的散列的「桶」中。通過這種方式,您的數據更容易訪問,因爲您無需在整個集合中查找此特定數據,只需查看合適的存儲區即可。

這種方式可以提高特定點的表現。

每個集合的實現都有其特殊性,以便在特定條件下使用它更好。這些特點中的每一個都有成本。因此,如果您不需要它(例如插入順序),則最好使用不提供它的實現,並且更符合您的要求。

-1

我不能引用參考,但通過設計ListSet接口的實現基本上可擴展Array s。由於Collections默認提供了動態的方法添加刪除元素在任何點 - 哪一個Array s不 - 可能不會保留插入順序。 因此,由於有更多的內容處理方法,所以需要特殊的實現來保持順序。

另一點是性能,因爲表現最好的Collection可能不是那個,它保留了它的插入順序。但我不確定,Collections如何管理其內容以提高性能。

因此,簡而言之,我能想到的,爲什麼有保序Collection實現的兩大原因是:

  1. Class架構
  2. 性能
+0

請注意,'Arrays'是一個實際的類,而數組是一種特殊類型的容器對象。我也非常確定LinkedList實際上使用鏈表,但我沒有閱讀代碼。 :-) – wds 2010-09-12 09:24:03

+0

好吧,點了,我編輯我的帖子。關於你的「LinkedList」評論:我發佈的內容與哪個矛盾? – FK82 2010-09-12 09:57:45

+0

澄清:LinkedList afaik是一個List,它的插入順序保存在另一個List中(其中兩個*鏈接*,因此是名稱)。或者,我錯了嗎? – FK82 2010-09-12 10:04:10

7
  • 廣告訂單本質上不保留在hash tables - 這是他們如何工作(閱讀鏈接到的文章,瞭解細節)。可以添加邏輯來維護插入順序(如LinkedHashMap),但需要更多的代碼,並且在運行時需要更多的內存和更多的時間。性能損失通常不顯着,但可以。
  • 對於TreeSet/Map,使用它們的主要原因是接口中添加的自然迭代順序和其他功能。
+2

+1提及「但需要更多代碼」。 – helpermethod 2010-09-12 10:03:16

+1

請注意:嚴格來說'Map'實現不是'Collection's,因爲它們沒有實現'Collection'接口。他們確實有類似的方法,但就是這樣。檢查:http://download.oracle.com/javase/1.4.2/docs/guide/collections/overview.html(#Collection Interfaces)雖然最有可能的OP的問題地址映射。 – FK82 2010-09-12 13:13:00

0

爲什麼有必要保持插入順序?如果您使用HashMap,則可以通過key獲取條目。這並不意味着它不提供你想要的類。

16

集合不保持插入順序。有些只是默認在最後添加一個新值。維護插入順序只有在按照對象的優先級排序或以某種方式對對象進行排序時纔有用。

至於爲什麼某些集合默認維護它,其他集合不這樣做,這主要是由實現引起的,並且有時只是集合定義的一部分。

  • 列表保持廣告訂單只是在末處加入一個新的條目或開始是最快實現的add(Object)方法的。

  • 集合 HashSet和TreeSet實現不維護插入順序,因爲對象被快速查找排序並且維護插入順序需要額外的內存。這會導致性能增益,因爲插入順序對於集合幾乎從未感興趣。

  • ArrayDeque一個deque可以用於簡單闕和堆棧,所以你想擁有'先進先出「」或「」後出「的行爲,都需要該ArrayDeque保持插入順序。在這種情況下,插入訂單將作爲類合同的核心部分進行維護。

+2

非常翔實,特別是關於ArrayDeque。 – Jayy 2013-05-10 11:21:02

0

即使世界在O'Reilly的Java的食譜一節名爲「避免衝動排序」你應該問的問題實際上是你原來的問題相反......「難道我們的排序有所收穫? 「分類和維護該訂單需要花費很多努力。當然,排序很簡單,但通常在大多數程序中不能擴展。如果您要每秒處理數千或數萬個請求(insrt,del,get等),那麼您是否正在使用已排序或未排序的數據結構,這將非常重要。

-1

好吧...所以這些帖子與現在相比是舊的,但是根據您的需要或應用程序要求,需要插入順序,因此只需使用正確類型的收集。大多數情況下,這不是必需的,但是在需要按照存儲順序使用對象的情況下,我看到了確切的需求。我認爲,在創建實例嚮導或流引擎時,訂單很重要,或者需要從一個狀態到另一個狀態或某事的某種性質。從這個意義上說,你可以讀取列表中的東西,而不必跟蹤你下一步需要的東西,或者遍歷列表來找到你想要的東西。它確實有助於在這個意義上的表現。它確實很重要,否則這些集合沒有多大意義。

0

一些Collection由於沒有維護順序,他們計算內容的hashCode並將其存儲在相應的bucket中。