2015-09-29 69 views
5

我得到的數據是這樣從LinkedHashMap的keySet()創建的ArrayList是否保留了插入的順序?

{ 「員工ABC 1」, 「ABCX」},{ 「僱員2 ABC的」, 「ABCY」}, { 「員工3 ABC的」,「ABCZ 「}

從數據庫中通過RefCursor

我有一種情況,我需要保持從數據庫中讀取數據的順序。 由於我的數據是'鍵值',我想使用Map這是有序的實現。因此選擇LinkedHashMap

//defined as a static map inside a common utlity class 
public class Common{ 
public static final LinkedHashMap<String, String> empMap = new LinkedHashMap<String, String>(); 
} 

//rs is the resultset 
if (rs != null) { 
      while (rs.next()) { 
       key = rs.getString("name_text"); 
       value = rs.getString("id"); 
       Common.empMap.put(key, value); 
      } 
} 

我不得不鑰匙傳遞給客戶端,在其中它被從數據庫中(光標)中檢索到的相同的順序。

​​

鍵設置() - 該文件說,「返回包含在此映射中鍵 的Set視圖set受映射支持,所以改變 地圖,反映在集,反之亦然」

我想到的是,由於ArrayList也是一個有序集合,我應該得到的鑰匙在其被檢索/插入Map以同樣的方式。

當我做一個樣本測試程序時,我得到了預期的結果。

public class LinkedMap {  
    public static void main(String[] args) { 
     LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();   
     map.put("Employee 1 of ABC", "ABCX"); 
     map.put("Employee 2 of ABC", "ABCY"); 
     map.put("Employee 3 of ABC", "ABCZ"); 
     ArrayList<String> list = new ArrayList<String>(map.keySet()); 
     System.out.println(list); 
    } 
} 

輸出:[ABC的僱員1,ABC的僱員2,ABC的僱員3]

但是我問題是,如果這是保證輸出或者是它,我我想起來了隨機,它可能會發生變化,

更新(?):2015年9月30日

謝謝大家,你們每個人都貢獻了有效的積分。

總之所有的答案,

這是保證秩序得以維持。

Javadocs

LinkedHashMap的是哈希表和地圖 接口的鏈接列表實現,具有可預知的迭代順序。該實現 與HashMap的不同之處在於它通過其所有條目維護運行 的雙向鏈表。此鏈接列表定義迭代 排序,這通常是在其中鍵分別插入 地圖(插入順序)的順序

即:LinkedHashMap將在其中條目放入的順序遍歷地圖

所以LinkedHashMap#keySet()會給我相同的順序,其中的鍵被插入地圖,因爲 LinkedHashMap#keySet().iterator()按指定的順序迭代。

深要去的iterator()實現中,我們可以看到,

LinkedHashMap的實現方法newKeyIterator()返回一個類繼承LinkedHashIterator的一個實例,同時將「排序」

// These Overrides alter the behavior of superclass view iterator() methods 
Iterator<K> newKeyIterator() { return new KeyIterator(); } ... 

private class KeyIterator extends LinkedHashIterator<K> {... 

private abstract class LinkedHashIterator<T> implements Iterator<T> { ... 
的護理

對於這一點:ArrayList<String> list = new ArrayList<String>(map.keySet()); 構造的ArrayList(集合)documented填補該eleme順序列表nts由指定的Collection的迭代器返回。

+0

我喜歡變量類型是最具體的'LinkedHashMap',而不是模糊的'Map' :) – ZhongYu

+0

我認爲,具有接口或具體類的引用對我的用例沒有什麼不同。但我必須承認,使用具體的類而不是接口是錯誤的。或者你感覺不一樣? – spiderman

+0

不,我認爲最好爲本地/實例變量使用最具體的類型。 – ZhongYu

回答

4

保證。

儘管Set接口本身並不能保證任何順序(好吧,LinkedHashSet),但Map實現本身保證插入順序的事實也保證了你也能按順序得到密鑰。由.keySet()返回的接口恰好是Set,因爲確保Map中的密鑰是唯一的。

如果不是,可以考慮在這種情況下會發生什麼:

// case 1 
for (final Map.Entry<K, V> entry: map.entrySet()) { 
    // entry.getKey(), entry.getValue() 
} 

// case 2 
for (final K key: map.keySet()) { 
    V value = map.get(key); 
} 

如果這兩個代碼有兩個不同的行爲,呃...

+0

謝謝+1,「由.keySet()返回的接口恰好是一個集合」 - 想到這個「集合」是什麼使我困惑 – spiderman

+0

我不明白你的觀點,比較兩個代碼:( – spiderman

+0

那麼,如果這兩個代碼迭代在一個不同的順序?甚至.values()? – fge

2

是的,這是保證。

在Oracle JDK中,類LinkedHashMap重新實現了方法newKeyIterator(),該方法返回繼承LinkedHashIterator的類的實例。那一個是有序的。

+0

非常有效的一個,+1我潛入它看到這個:) – spiderman

1

其他的答案解釋指定的順序LinkedHashMap#keySet().iterator()迭代,所以讓我補充:

ArrayList Javadoc中說,大約ArrayList(Collection)

構造一個包含指定集合中的元素,在列表它們由集合的迭代器返回。

因此保證ArrayList項目將以相同的順序。

+0

得到它謝謝+1 – spiderman

1

確保LinkedHashSet的迭代順序與插入鍵的順序相同(假設您沒有使用特殊的構造函數來允許您通過最近的訪問來請求排序)。你可以在its documentation找到它。

我想你可能會說,迭代順序擔保只適用於條目集,而不是其他的意見,但該文檔不支持很好(因爲它們是指迭代順序),和在實踐中,集合視圖確實共享一個共同的迭代順序。

對於它的部分,構造函數ArrayList(Collection)is documented以指定的Collection的迭代器返回元素的順序填充列表。

1

正如Does entrySet() in a LinkedHashMap also guarantee order?這個問題所述,並在JavaDocs中指出,迭代類型操作定義爲LinkedHashMap的插入順序。這會影響keySet,因爲它會影響entrySet

ArrayList的構造函數將按照迭代器的順序插入到List中。

這兩個條件相結合,意味着API保證了這種行爲。

+0

好的,參考文獻+1 – spiderman

相關問題