Добавление данных на карту в Java - PullRequest
4 голосов
/ 06 января 2011

У меня есть карта

Map<Integer, List<Object>> entireData;

Теперь к этому я добавляю некоторые данные, используя putAll, например

entireData.putAll(someData);

, где someData возвращает Map<Integer, List<Object>>

ТеперьУ меня есть другая строка, которая говорит

entireData.putAll(someMoreData);

, которая также возвращает Map<Integer, List<Object>>, но, делая это, она перезаписывает содержимое существующего wholeData, как мне добавить?

Ответы [ 6 ]

6 голосов
/ 06 января 2011

Вы хотите Мультикарта из Google Guava .Переписав ваш пример с использованием Gumap Multimap:

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

entireData.get(key) возвращает List<Object>.putAll не будет переопределять старые ключи, но добавит значения этих ключей к существующим значениям.Это также намного приятнее, чем самостоятельная инициализация List экземпляров.

6 голосов
/ 06 января 2011

Первая строка класса Java Map Reference:

Объект, который сопоставляет ключи со значениями. карта не может содержать дубликаты ключей; каждый ключ может отображать не более одного значения.

4 голосов
/ 06 января 2011
for (Integer key : someMoreData.keySet())
{
    if (entireData.containsKey(key))
    {
        entireData.get(key).addAll(someMoreData.get(key));
    }
    else
    {
        entireData.put(key, someMoreData.get(key));
    }
}
2 голосов
/ 06 января 2011

По умолчанию Java Maps отображает один ключ на одно значение, , как троянская программа пишет . Если этого недостаточно для ваших нужд, вам нужна реализация Multi-Map (Карта, которая сопоставляет ключ с набором значений).

Самые популярные версии можно найти в двух открытых фреймворках, Google Guava и Apache Commons / Collections .

Пример гуавы:

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

Выход:

[foo, bar]

Пример коллекции коллекций:

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

Выход:

[foo, bar]

Как вы можете видеть, версия Commons Collections намного проще, но она также менее мощна, и в текущей версии она не поддерживает дженерики Java 1.5. Так что я бы пошел с гуавой.

2 голосов
/ 06 января 2011

Ключи уникальны. Если someMoreData имеет ключ такой же, как уже существующий ключ в entireData, то значение, т. Е. Список объектов, будет перезаписан.

Однако вы можете ввести someMoreData и добавить ключи, которые существуют в entireData, например

 for(Integer key: someMoreData.keySet()){
       if(entireData.get(key)!=null)
           entireData.get(key).addAll(someMoreData.get(key));
       else
           entireData.put(key,someMoreData.get(key));
 }
0 голосов
/ 11 июля 2018

похоже на willcodejavaforfood Ответы не нужны, но вместо этого используется набор записей для меньшего количества запросов HashMap.

public static <K,V> void appendMapBtoMapA(HashMap<K,List<V>> a, HashMap<K,List<V>> b) {
    for (Map.Entry<K, List<V>> bEntry : b.entrySet()) {
        if (a.containsKey(bEntry.getKey())) {
            a.get(bEntry.getKey()).addAll(bEntry.getValue());
        } else {
            a.put(bEntry.getKey(), bEntry.getValue());
        }
    }
}

или Nishant , который отбрасывает содержащий вызов и добавляет нулевую проверку, но с entrySet

public static <K,V> void appendMapBtoMapA(HashMap<K,List<V>> a, HashMap<K,List<V>> b) {
    for (Map.Entry<K, List<V>> bEntry : b.entrySet()) {
        List<V> aValue = a.get(bEntry.getKey());
        if (aValue != null) {
            aValue.addAll(bEntry.getValue());
        } else {
            a.put(bEntry.getKey(), bEntry.getValue());
        }
    }
}

или с Java 8

public static <K,V> void appendMapBtoMapA(HashMap<K,List<V>> a, HashMap<K,List<V>> b) {
    for (Map.Entry<K, List<V>> bEntry : b.entrySet()) {
        a.computeIfAbsent(
            bEntry.getKey(), 
            k -> new LinkedList<>()
        ).addAll(bEntry.getValue());
    }
}
...