2016-06-21 15 views
2

Ist es möglich, die Liste der Werte von HashMap als Referenz erhaltenGet Werte von HashMap als Referenz

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); 
} 

Ausgabe

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

hier, wenn Werteliste erhalten aus HashMap es gibt Deep-Kopie zurück.

aktualisieren

Meine Anforderung

  1. Ich möchte Liste von Werten aus HashMap, weil ich Elemente zuzugreifen, um ihre Position
  2. wollen möchte ich Reihenfolge der Werte bewahren
  3. Wenn ich etwas in der extrahierten Liste ändere, sollte es auch in HashMap reflektiert werden

Bitte erzählen, wenn Dritte Bibliothek solche Datenstruktur zur Verfügung stellen, oder, was am besten Ansatz wäre diese Situation

+2

'Liste list = new ArrayList <> (map.values ​​());' Was denken Sie, was diese Zeile macht? – Fildor

+0

Es ist flache Kopie, was genau willst du? – Boola

+0

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

Antwort

2

Versuchen Sie, die Karteneinträge zu verwenden, die von der Karte unterstützt werden und die Sie erhalten, indem Sie entrySet() aufrufen. Eine Liste von denen funktioniert fast so, wie Sie es wollen (obwohl ich immer noch befürworte, dass Sie direkt map.put(key, updatedValue) verwenden.

Beispiel:

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) 

Ein letzter Hinweis aber: wie ich schon in meinem Kommentar angegeben, wenn sie mit einer Karte, um den Umgang nicht immer deterministisch ist (es sei denn, Sie wissen, dass Sie mit einer geordneten Karte wie TreeMap zu tun hat) und die Verwendung von Indizes kann zu Fehlern oder unerwünschtem Verhalten führen. Deshalb sollten Sie zumindest in den meisten Fällen den Schlüssel überprüfen, und Sie müssen entweder Map.Entry verwenden (wobei der Schlüssel aus gutem Grund nicht geändert werden kann) oder den Schlüssel direkt verwenden. In diesem Fall nicht brauche sowieso eine Liste/Sammlung von Werten oder Einträgen.

+0

Dies ist am nächsten, was ich brauche – penguin

+0

Wird Reihenfolge deterministisch sein, wenn ich LinkedHashMap anstelle von HashMap verwende? Will map.entrySet() liefern Daten in der gleichen Reihenfolge immer – 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

Sie schaffen eine neue List basierend auf den Werten der Map zu handhaben:

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

Das ist, was die Kopie der Werte Collection erstellt, und Änderungen in diesem List können nicht in der ursprünglichen Map widergespiegelt werden.

Wenn Sie die von map.values() zurückgegebene Sammlung direkt ändern (z. B. map.values().remove(new MyCustomObject("abc",1))), wird dies im Inhalt der ursprünglichen Map widergespiegelt. Sie könnten set auf dem Collection jedoch nicht aufrufen, da Collection diese Methode nicht hat.

2

Sammlung values ​​()

Gibt eine Sammlung Blick auf die in dieser Karte enthaltenen Werte. Die Sammlung wird von der Karte unterstützt, sodass Änderungen an der Karte in der Sammlung widergespiegelt werden und umgekehrt.

Verwenden Sie also eine Sammlung und weisen Sie ihr values() zu. Oder die entrySet().

+0

Genau das, was ich vorschlagen würde, d. H. Verwenden Sie 'entrySet()' zusammen mit 'entry.setValue (...)', um diesen Eintrag zu aktualisieren. – Thomas

+0

@Thomas +1 von mir, entrySet ist da draußen mehr als Werte verwendet, da der Schlüssel oft eine Rolle spielt. –