Как поставить все содержимое Java hashMap одного на другое, но не заменить существующие ключи и значения? - PullRequest
76 голосов
/ 25 августа 2011

Мне нужно скопировать все ключи и значения из одной A HashMap в другую B, но не заменять существующие ключи и значения.

Какой лучший способ сделать это?

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

Map temp = new HashMap(); // generic later
temp.putAll(Amap);
A.clear();
A.putAll(Bmap);
A.putAll(temp);

Ответы [ 6 ]

101 голосов
/ 25 августа 2011

Похоже, вы готовы создать временный Map, поэтому я бы сделал это так:

Map tmp = new HashMap(patch);
tmp.keySet().removeAll(target.keySet());
target.putAll(tmp);

Здесь patch - карта, которую вы добавляете к карте target.

Благодаря Луи Вассерману, вот версия, которая использует преимущества новых методов в Java 8:

patch.forEach(target::putIfAbsent);
15 голосов
/ 25 августа 2011

Используя Guava 's Maps * служебные методы класса class', чтобы вычислить разницу двух карт, вы можете сделать это в одной строке с сигнатурой метода, которая делает более понятным, чтоВы пытаетесь выполнить:

public static void main(final String[] args) {
    // Create some maps
    final Map<Integer, String> map1 = new HashMap<Integer, String>();
    map1.put(1, "Hello");
    map1.put(2, "There");
    final Map<Integer, String> map2 = new HashMap<Integer, String>();
    map2.put(2, "There");
    map2.put(3, "is");
    map2.put(4, "a");
    map2.put(5, "bird");

    // Add everything in map1 not in map2 to map2
    map2.putAll(Maps.difference(map1, map2).entriesOnlyOnLeft());
}
8 голосов
/ 25 августа 2011

Просто итерируйте и добавьте:

for(Map.Entry e : a.entrySet())
  if(!b.containsKey(e.getKey())
    b.put(e.getKey(), e.getValue());

Изменить, чтобы добавить:

Если вы можете внести изменения в a, вы также можете сделать:

a.putAll(b)

и будет иметь именно то, что вам нужно. (все записи в b и все записи в a, которых нет в b)

5 голосов
/ 22 марта 2016

Вы можете сделать это всего за 1 строку, если измените порядок карт в решении @ erickson:

mapWithNotSoImportantValues.putAll( mapWithImportantValues );

В этом случае вы заменяете значения в mapWithNotSoImportantValues ​​значением из mapWithImportantValues ​​теми же ключами.

2 голосов
/ 13 февраля 2017

В Java 8 есть этот метод API для выполнения ваших требований.

map.putIfAbsent(key, value)

Если указанный ключ еще не связан со значением (или сопоставлен со значением NULL), связывает его с данным значением и возвращает значение NULL, иначе возвращается текущее значение.

2 голосов
/ 28 декабря 2016
public class MyMap {

public static void main(String[] args) {

    Map<String, String> map1 = new HashMap<String, String>();
    map1.put("key1", "value1");
    map1.put("key2", "value2");
    map1.put("key3", "value3");
    map1.put(null, null);

    Map<String, String> map2 = new HashMap<String, String>();
    map2.put("key4", "value4");
    map2.put("key5", "value5");
    map2.put("key6", "value6");
    map2.put("key3", "replaced-value-of-key3-in-map2");
    // used only if map1 can be changes/updates with the same keys present in map2.
    map1.putAll(map2);

    // use below if you are not supposed to modify the map1.
    for (Map.Entry e : map2.entrySet())
        if (!map1.containsKey(e.getKey()))
            map1.put(e.getKey().toString(), e.getValue().toString());
    System.out.println(map1);
}}
...