2011-01-29 20 views
9

chcę dodać zduplikowane elementy na hashmapJava HashMap zduplikowane elementy

tak:

put("name1", 1); 
put("name1", 3); 
put("name1", 3); 
put("name2", 1); 
put("name2", 3); 

w jaki sposób można to zrobić?

+0

jaka jest korzyść z tego? co starasz się osiągnąć, może jest lepszy sposób na zrobienie tego, jeśli dasz więcej deatils – ant

Odpowiedz

13

Użyj Map<String, List<Integer>>, tj. Zamapuj ciąg znaków na listę liczb całkowitych.

Tak więc w tym przypadku name1 zostanie odwzorowane na listę [1,3,3].

Oczywiście musisz napisać własną metodę put, w której dodajesz int do listy. Przykład:

put(String s, int i){ 
    List<Integer> list = map.get(s); 
    if(list == null){ 
     list = new ArrayList<Integer>(); 
     map.put(s, list); 
    } 
    list.add(i); 
} 
0

Nie można, można jednak utworzyć własną implementację mapy, która pozwala na duplikowanie w środku.

+2

Jeśli pozwala na duplikaty, to nie jest 'Mapą'. – finnw

+0

@finnw true (pad ..) – ant

+0

ok, czy nie ma "mapy", która to pozwala? jak się nazywa? – lacas

13

ListMultimap interfejs z Guava może sprostać Państwa wymaganiom. Umożliwia duplikowanie kluczy i duplikatów par klucz/wartość.

ListMultimap<String, Integer> m = 
    ArrayListMultimap.create(); 
m.put("name1", 1); 
m.put("name1", 3); 
m.put("name1", 3); 
m.put("name2", 1); 
m.put("name2", 3); 
System.out.println(m.get("name1")); // => [1, 3, 3] 
System.out.println(m.get("name2")); // => [1, 3] 

Czy naprawdę potrzebujesz zachować zduplikowane pary klucz/wartość? (. I bardziej wydajne), jeśli nie wtedy HashMultimap może być wystarczająca, jeśli włożysz te same wpisy w HashMultimap otrzymasz:

System.out.println(m.get("name1")); // => [1, 3] 
System.out.println(m.get("name2")); // => [1, 3] 
+0

+1 - to właśnie bym zrobił. – CoolBeans

5

Twój pomysł jest niezgodny umowy interfejsu Map:

An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.

Byłoby zrozumiałe być mylące na mapie, gdy pytasz:

map.get("name1") 

It nie wiedziałbym, jaką wartość uzyskać.

Chciałbym użyć rozwiązania dogbane mapowania każdego klucza na listę liczb całkowitych. W twoim przykładzie możesz mieć zduplikowane wartości. Jeśli nie chcesz, aby zduplikowane wartości (np. Dla "nazwa1" były tylko jedną 3 na wynikowej liście), możesz zamiast tego uczynić z niej Mapę Ciągów do Sets Integers.

3

Powinieneś użyć struktury danych Google Collection o Multimap.

Kolekcja podobny do mapą, ale które mogą skojarzyć wiele wartości pomocą jednego klawisza. Jeśli wywołasz dwukrotnie (K, V) z tym samym kluczem, ale inne wartości, ale , multimap zawiera mapowania z klucza do obu wartości .

To jest dokładnie to, co próbujesz osiągnąć. Nie ma potrzeby ponownego wynajdywania koła, pisząc własne operacje na mapie w mojej opinii. Możesz również znaleźć ten tutorial na MultiMap przydatne.

+0

Dokładniej myślę, że musiałby to być 'ListMultimap'. 'SetMultimap' nie zezwala na zduplikowanie par klucz/wartość, ale jest na przykład w danych wejściowych. Ten artykuł jest nieco przestarzały. Kolekcje Google zostały połączone w [Guava] (http://code.google.com/p/guava-libraries/). – finnw

+0

W prawo. Lub możesz użyć HashMultimap – CoolBeans

+0

'HashMultimap' pozwala na duplikowanie kluczy, ale nie duplikowanie par klucz/wartość. Jeśli wstawisz przykładowe wpisy do 'HashMultimap', otrzymasz tylko jeden wpis' name1 = 3'. – finnw

0

org.apache.commons.collections.map.MultiValueMap jest bardziej odpowiednim wyborem. Może umieścić jeden klucz w wielu wartościach.

public Object put(Object key, Object value) { 
    boolean result = false; 
    Collection coll = getCollection(key); 
    if (coll == null) { 
     coll = createCollection(1); 
     result = coll.add(value); 
     if (coll.size() > 0) { 
      // only add if non-zero size to maintain class state 
      getMap().put(key, coll); 
      result = false; 
     } 
    } else { 
     result = coll.add(value); 
    } 
    return (result ? value : null); 
}