2011-09-07 38 views
4

我正在尋找一個不斷排序的java列表,它也可以用來快速檢索一個對象。 PriorityQueue非常適合「不斷排序」的需求,HashMap非常適合按鍵快速檢索,但我需要在同一個列表中。在某一時刻,我寫了自己的,但它沒有實現集合接口(所以不能用作java.util.List等的替代品),我寧願遵守標準的java類如果可能的話。java不斷排序列表與快速檢索

那裏有這樣的列表嗎?現在我使用2個列表,一個優先級隊列和一個hashmap,它們都包含相同的對象。我使用優先級隊列以排序順序遍歷列表的第一部分,通過鍵快速檢索hashmap(我需要同時執行兩個操作),但我希望有一個更優雅的解決方案...

編輯:我應該補充一點,我需要有一個不同的比較器排序的列表,然後用key來檢索;該列表按長整型值排序,關鍵檢索是一個String。

回答

2

由於您已經在使用HashMap,這意味着您擁有唯一的密鑰。假設你想要通過這些鍵來訂購,TreeMap就是你的答案。

+0

感謝您的回覆......請參閱我的編輯幾秒鐘前,我不認爲TreeMap將在這裏工作。 – user85116

+0

@ user85116 - 不,它不會。但是你的問題並沒有提供足夠的信息來給出一個好的答案。例如,你說你正在使用PriorityQueue。這是否意味着你只關心「列表」中的第一個項目被分類?或者你想要一個總的順序(在這種情況下,PriorityQueue是錯誤的選擇)。如果你用你的實際用例編輯你的問題,那麼我將編輯答案。 – parsifal

+0

我不明白爲什麼PriorityQueue是錯誤的選擇;正如我的問題所提到的,有時我需要按照排序順序遍歷列表的第一部分(不是整個列表,只是開頭的幾個元素)(PriorityQueue相當不錯);我的問題是,在其他時間,我需要從列表中獲取基於鍵的項目,並且此查找需要很快。 – user85116

2

這聽起來像你說什麼是自動維護索引的集合。

嘗試查看GlazedLists,它們使用「列表管道」來高效地傳播更改 - 它們的類應該完成這項工作。

編輯:錯過了您的按鍵檢索要求。這可以通過GlazedLists.syncEventListToMapGlazedLists.syncEventListToMultimap完成 - 如果沒有重複的鍵,syncEventListToMap可以工作,如果有重複的鍵,syncEventListToMultimap可以工作。這種方法的好處在於,您可以根據不同的索引創建多個地圖。


如果你要使用索引樹圖 - 這可能會給你更好的性能 - 你需要保持你的樹狀圖自定義類您選擇,暴露你想要的接口/方法的範圍內私自封裝,併爲該類創建訪問器/修改器以使索引與集合保持同步。如果您從多個線程訪問集合,請務必處理併發問題(通過​​方法或鎖或其他)。


編輯:最後,如果在排序順序的項目快速遍歷是很重要的,可以考慮使用ConcurrentSkipListMap而不是樹形圖 - 不是它的併發性,但其快速的穿越。 Skip lists是具有多級聯動的鏈表,其中一個遍歷所有項目,下一個平均遍歷每K個項目(對於給定的常量K),下一個平均遍歷每個項目等。

0

TreeSet繼續。

基於TreeMap的NavigableSet實現。這些元素使用它們的自然順序或者在創建集合時提供的比較器進行排序,具體取決於使用哪個構造函數。

此實現爲基本操作(添加,刪除和包含)提供了有保證的log(n)時間成本。

0

我沒有測試過,所以我可能是錯的,所以認爲這只是一個嘗試。 使用TreeMap,將該映射的關鍵字封裝爲具有兩個屬性(在hashmap中用作關鍵字的字符串,以及用於在PriorityQueue中維護排序順序的長字符串)的對象。現在爲這個對象重寫使用字符串的equals和hashcode方法。使用long來實現可比較的接口。

0

爲什麼不將自己的解決方案封裝到實現Collection或Map的類中?
通過這種方式,您可以簡單地將檢索方法委託給更快/更好的適合集合。只要確保調用write-methods(add/remove/put)將被轉發到這兩個集合。記住間接訪問,如iterator.remove()。大多數這些方法是可選的實現,但你必須停用它們(Collections.unmodifiableXXX將在大多數情況下在這裏幫助)。