How to putAll on Java hashMap contents of one to another, but not replace existing keys and values?

I need to copy all keys and values from one A HashMap onto another one B, but not to replace existing keys and values.

Whats the best way to do that?

I was thinking instead iterating the keySet and checkig if it exist or not, I would

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

Answers


It looks like you are willing to create a temporary Map, so I'd do it like this:

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

Here, patch is the map that you are adding to the target map.

Thanks to Louis Wasserman, here's a version that takes advantage of the new methods in Java 8:

patch.forEach(target::putIfAbsent);

Using Guava's Maps class' utility methods to compute the difference of 2 maps you can do it in a single line, with a method signature which makes it more clear what you are trying to accomplish:

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

Just iterate and add:

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

Edit to add:

If you can make changes to a, you can also do:

a.putAll(b)

and a will have exactly what you need. (all the entries in b and all the entries in a that aren't in b)


You can make it in just 1 line if you change maps order in @erickson's solution:

mapWithNotSoImportantValues.putAll( mapWithImportantValues );

In this case you replace values in mapWithNotSoImportantValues with value from mapWithImportantValues with the same keys.


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

With Java 8 there is this API method to accomplish your requirement.

map.putIfAbsent(key, value)

If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value.


Need Your Help

Create .ics file dynamically

php icalendar

I made a website for a client where they can post events. Instead of manually creating .ics files from iCal for every event and uploading it, I though it would be better to pull it out of the datab...

How to set application's taskbar icon in Windows 7

qt windows-7 pyqt

How do I set an application's taskbar icon in PyQt4?