2016-06-21 124 views
2

是否有可能從HashMap獲取值的列表作爲參考獲取值作爲參考

class MyCustomObject { 
    String name; 
    Integer id; 

    MyCustomObject(String name, Integer id){ 
     this.name = name; 
     this.id = id; 
    } 
} 
HashMap<Integer, MyCustomObject> map = new LinkedHashMap<>(); 
map.put (1, new MyCustomObject("abc",1)); 
map.put (2, new MyCustomObject("xyz",2)); 

List<MyCustomObject> list = new ArrayList<>(map.values()); 

Log.i(TAG,"************ List from HashMap ************"); 
for (MyCustomObject s : list) { 
    Log.i(TAG,"name = "+s.name); 
} 

list.set(0,new MyCustomObject("temp",3)); 

Log.i(TAG,"************ List from HashMap after update ************"); 
for (MyCustomObject s : list) { 
     Log.i(TAG,"name = "+s.name); 
} 

Log.i(TAG,"************ List from HashMap ************"); 

List<MyCustomObject> list2 = new ArrayList<>(map.values()); 
for (MyCustomObject s : list2) { 
    Log.i(TAG,"name = "+s.name); 
} 

輸出

**************** List from HashMap *************** 
name = abc 
name = xyz 
**************** List from HashMap after update *************** 
name = temp 
name = xyz 
**************** List from HashMap *************** 
name = abc 
name = xyz 

這裏,如果從獲取值的列表HashMap它返回深度複製。

更新

我的要求

  1. 我想從HashMap中值的列表,因爲我想用自己的位置
  2. 訪問項目我想保留值的順序
  3. 如果我在提取的列表中修改任何內容,那麼它也應該反映在HashMap中

請不要告訴,如果任何第三方庫提供這樣的數據結構,或者這將是處理這種情況

+2

'List list = new ArrayList <>(map.values());'你認爲這行代表什麼? – Fildor

+0

這是淺拷貝,你想要什麼? – Boola

+0

劇透:https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList(java.util.Collection) – Fildor

回答

2

嘗試使用地圖支持的地圖條目,並通過致電entrySet()獲取地圖條目。這些幾乎可以像你想要的那樣工作(儘管我仍然主張你直接使用map.put(key, updatedValue)

例子:

Map<String, Integer> map = new HashMap<>(); 
map.put("a", 1); 
map.put("b", 2); 

//you create a list that's not backed by the map here but that isn't a problem 
//since the list elements, i.e. the entries, are backed by the map 
List<Entry<String, Integer>> entryList = new ArrayList<>(map.entrySet()); 
entryList.get(0).setValue(5); 

System.out.println(map); //prints: {a=5, b=2} (note that order is a coincidence here) 

最後要注意,雖然:正如我在我的評論與地圖秩序打交道時已經說明並非總是確定性的(除非你知道你在處理像TreeMap一個有序圖)因此使用索引可能會引入錯誤或不良行爲。這就是爲什麼你至少要在大多數情況下檢查密鑰,因此你需要使用Map.Entry(因爲很好的原因,它不能改變密鑰),或者直接使用密鑰,在這種情況下你不需要無論如何需要一個列表/值的集合或條目。

+0

這是最接近我需要的 – penguin

+0

如果我使用LinkedHashMap而不是HashMap,順序會是確定性的嗎?將map.entrySet()提供的數據總是相同的順序 – penguin

+0

http://stackoverflow.com/questions/2923856/is-the-order-guaranteed-for-the-return-of-keys-and-values-from-a -linkedhashmap -o/2924143#2924143 – penguin

4

您是基於Map的值創建一個新的List最好的方法:

List<MyCustomObject> list = new ArrayList<>(map.values()); 

這就是創建值Collection的副本,並且該List中的更改不能反映在原始Map中。

如果您直接修改map.values()返回的集合(例如,map.values().remove(new MyCustomObject("abc",1))),它將反映在原始Map的內容中。不過,您不能在Collection上撥打set,因爲Collection沒有該方法。

2

類別值()

返回包含在此圖中的值的集合圖。 集合由地圖支持,因此對地圖的更改將在集合中反映爲 ,反之亦然。

因此,使用Collection並將values()賦值給它。或者entrySet()

+0

正是我建議的,即使用'entrySet()'和'entry.setValue(...)'來更新該條目。 – Thomas

+0

@Thomas +1來自我,entrySet比鍵值經常扮演的角色更多地被用在那裏。 –