2011-01-06 11 views
3

ich eine Karte habenAnfügen von Daten in Java Karte

Map<Integer, List<Object>> entireData; 

Nun ist diese ich einige Daten bin Zugabe mit putAll wie

entireData.putAll(someData); 

wo some kehrt Map<Integer, List<Object>>

Nun, ich habe eine andere Zeile die sagt

entireData.putAll(someMoreData); 

, die auch Map<Integer, List<Object>> zurückgibt, aber dadurch überschreibt es den Inhalt der vorhandenen gesamtenDaten, wie hänge ich an?

Antwort

5

Erste Zeile der Java Karte Klasse Referenz:

Ein Objekt, das Schlüssel auf Werte abbildet. Eine Karte darf keine doppelten Schlüssel enthalten. Jeder Schlüssel kann höchstens einem Wert zugeordnet werden.

+0

true, ich stimme zu, die Schlüsselwerte sind hier anders aber – Vivek

+1

Hmmm, das soll nicht passieren! putAll() entspricht dem Aufruf von put() für alle Elemente in der Quellensammlung. – trojanfoe

+0

Ihr Kommentar hat mich tatsächlich dazu gebracht, meinen Code noch einmal zu betrachten, und da merkte ich, dass meine Codeänderung am vorherigen Tag die Schlüsselwerte zurückgesetzt hatte :(. – Vivek

5

Sie möchten eine Multimap von Google Guava. Umschreiben von Ihrem Beispiel mit Guava Multimap:

ListMultimap<Integer, Object> entireData = ArrayListMultimap.create(); 

entireData.get(key) eine List<Object> zurückgibt. putAll überschreibt keine alten Schlüssel, sondern fügt die Werte dieser Schlüssel an die vorhandenen Werte an. Dies ist auch viel schöner als mit der Initialisierung der List Instanzen selbst zu tun.

+0

Zeit zu Guava Antwort ... ca. 7 Minuten –

+0

Es gibt einen Grund, es ist die beste Sammlung Bibliothek da draußen! – sjr

4
for (Integer key : someMoreData.keySet()) 
{ 
    if (entireData.containsKey(key)) 
    { 
     entireData.get(key).addAll(someMoreData.get(key)); 
    } 
    else 
    { 
     entireData.put(key, someMoreData.get(key)); 
    } 
} 
+0

Ja, diese Art von Code ist genau das, was Sie für eine Multimap-Implementierung benötigen. – sjr

+1

+1 direkteste Antwort –

2

Schlüssel sind einzigartig. Wenn someMoreData einen Schlüssel hat, der dem bereits vorhandenen Schlüssel in entireData entspricht, wird der Wert, d. H. Die Liste des Objekts, überschrieben.

Allerdings wird auch hier in someMoreData und für Schlüssel anhängen, die wie

in entireData existiert
for(Integer key: someMoreData.keySet()){ 
     if(entireData.get(key)!=null) 
      entireData.get(key).addAll(someMoreData.get(key)); 
     else 
      entireData.put(key,someMoreData.get(key)); 
} 
2

Pro standardmäßig Java Karten Karte ein Schlüssel zu einem Wert, as trojanfoe writes. Wenn dies Ihren Anforderungen nicht genügt, benötigen Sie eine Multi-Map-Implementierung (Eine Map, die von einem Schlüssel auf eine Sammlung von Werten zuordnet).

Die gängigsten Versionen finden sich in zwei Open-Source-Frameworks, Google Guava und Apache Commons/Collections.

Guava Beispiel:

final Multimap<Integer, String> mmap = 
    Multimaps.newSetMultimap(
     Maps.<Integer, Collection<String>> newHashMap(), 
     new Supplier<Set<String>>(){ 

      @Override 
      public Set<String> get(){ 
       return Sets.newHashSet(); 
      } 
     }); 
mmap.put(1, "foo"); 
mmap.put(1, "bar"); 
System.out.println(mmap.get(1)); 

Output:

[foo, bar]

Commons Collections Beispiel:

final MultiMap mmap = new MultiHashMap(); 
mmap.put(1, "foo"); 
mmap.put(1, "bar"); 
System.out.println(mmap.get(1)); 

Ausgang:

[foo, bar]

Wie Sie sehen können, die Commons Sammlungen Version ist viel einfacher, aber es ist auch weniger stark, und in der aktuellen Version es doesn Java Generics nicht unterstützen. Also würde ich mit Guava gehen.

+0

Sie können eine Guava 'Multimap' _much_ einfacher mit einem von' Multimaps.new [(Linked? Hash) | Baum] Multimap.create() 'instanziieren (ok, vielleicht dass" regex "isn ' t perfekt ;-) –

+0

... auf jeden Fall +1, um zu demonstrieren, wie man die Generika mit 'newSetMultimap (Maps.newHashMap(), ...) richtig bringt, was genau ich *** brauchte. –