2011-01-06 2 views
3

У меня есть картадобавляющим данные Карта в Java

Map<Integer, List<Object>> entireData; 

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

entireData.putAll(someData); 

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

Теперь я имеют другую строку, в которой говорится:

entireData.putAll(someMoreData); 

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

ответ

5

Первая линия Java карт класса Reference:

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

+0

Настоящий, я согласен, ключевые значения здесь разные, но – Vivek

+1

Хммм, это не должно произойти! putAll() совпадает с вызовом put() для всех элементов в исходной коллекции. – trojanfoe

+0

, вы прокомментировали, что заставило меня снова взглянуть на мой код, и именно тогда я понял, что мое изменение кода предыдущего дня вызвало сброс значений ключа :( – Vivek

5

Вы хотите получить Multimap от Google Guava. Переписывая ваш пример с Гуавой Multimap:

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

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

+0

Время ответа Гува ... около 7 минут –

+0

Существует причина, по которой это лучшая коллекция библиотеки! – 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

Да, такой код - это именно то, для чего вам нужна реализация Multimap. – sjr

+1

+1 самый прямой ответ –

2

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

Однако вы можете цикл в 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)); 
} 
2

По-умолчанию, Java Maps карта один ключ к одному значению, as trojanfoe writes. Если этого недостаточно для ваших нужд, вам нужна реализация 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, бар]

фонда Коллекции Пример:

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

Выход:

[Foo, бар]

Как вы можете видеть, версия Commons Коллекции намного проще, но и менее мощный, и в текущей версии это Безразлично 't поддерживает Java 1.5 generics. Поэтому я поеду с Гуавой.

+0

Вы можете создать экземпляр Guma 'Multimap' _much_ более просто, используя один из' Multimaps.new [(Linked? Hash) | Tree] Multimap.create() '(хорошо, возможно, что« regex »isn ' t perfect ;-) –

+0

... во всяком случае, +1 для демонстрации того, как правильно получить дженерики с помощью 'newSetMultimap (Maps.newHashMap(), ...)', что и требовалось ***. –

Смежные вопросы