1

Say I have a map like

{one=1; two=1; three=1}

and another map like

{one=4; two=4; three=4}

I know that putAll() would add unique keys and replace existing keys. Will it be possible to do an addition of both the maps which would produce a result like adding the values whenever there is an existing keyword.

{one=5; two=5; three=5}
Prasanna
  • 2,593
  • 7
  • 39
  • 53
  • 2
    Yes, approx. 5-6 lines of code. Have you tried anything? – jlordo Feb 28 '13 at 13:17
  • 2
    see here http://stackoverflow.com/questions/11223561/how-can-i-sum-the-values-in-two-maps-and-return-the-value-using-guava – PSR Feb 28 '13 at 13:20
  • Loop through one map, get value for matching key in second map, sum both values and set it back to second map. Try it and let us know the result. – Harry Joy Feb 28 '13 at 13:20
  • 1
    Do you want to know whether there is a provided method (like `putAll`) that will do it for you? Or are you asking us to write the code for you? – Raedwald Feb 28 '13 at 13:26
  • Just wanted to keep the question simple. I am trying out some parallel programming where I would have 4 maps of size approximately 2/3GB each. So thought looping through them would be taxing on my processor and wanted to know if there is any available method. Thanks. – Prasanna Mar 01 '13 at 20:16

4 Answers4

0

Create a new Map, then for all entries x in map1, if map2 contains key x, put the addition of both values into the new map with key x.

Xavi López
  • 27,550
  • 11
  • 97
  • 161
0

try this ,

             Map<String, Integer> map = new HashMap<String, Integer>();
    Map<String, Integer> map1 = new HashMap<String, Integer>();
             Map<String, Integer> map2 = new HashMap<String, Integer>();

    map.put("one", 1);
    map.put("two", 1);
    map.put("three", 1);

    map1.put("one", 4);
    map1.put("two", 4);
    map1.put("three", 4);


    for (Map.Entry<String, Integer> entry : map.entrySet()) {
        System.out.println(map1.get(entry.getKey())+entry.getValue());
                        map2.put(entry.getKey(),map1.get(entry.getKey())+entry.getValue());
    }
PSR
  • 39,804
  • 41
  • 111
  • 151
0

Extend the HashMap and override the putAll method.

public class MyMap extends java.util.HashMap{
 @Override
 public void putAll(java.util.Map mapToAdd){
      java.util.Iterator iterKeys = keySet().iterator();
      while(iterKeys.hasNext()){
           String currentKey = (String)iterKeys.next();
           if(mapToAdd.containsKey(currentKey)){
                mapToAdd.put(currentKey, new Integer(Integer.parseInt(get(currentKey).toString()) + Integer.parseInt(mapToAdd.get(currentKey).toString())));
           }else{
                mapToAdd.put(currentKey, get(currentKey));
           }
      }
      super.putAll(mapToAdd);
 }
 public static void main(String args[]){
     MyMap m1 = new MyMap();
     m1.put("One", new Integer(1));
     m1.put("Two", new Integer(2));
     m1.put("Three", new Integer(3));
     MyMap m2 = new MyMap();
     m2.put("One", new Integer(4));
     m2.put("Two", new Integer(5));
     m2.put("Three", new Integer(6));
     m1.putAll(m2);
     System.out.println(m1);
 }

}

Now, create objects of MyMap instead of HashMap. Created a fiddle Here

Ravindra Gullapalli
  • 9,049
  • 3
  • 48
  • 70
  • 1
    But I believe the implementation in `HashMap` might be doing additional stuffs that will get skipped with this overriden method. –  Feb 28 '13 at 13:36
  • 1
    For example - I just found a `resize` method getting called inside `putAll` in certain scenarios. –  Feb 28 '13 at 13:43
  • @NishantShreshth Updated my answer with super.putAll so that our implementation do not skip the actual HashMap implementation. – Ravindra Gullapalli Feb 28 '13 at 13:52
  • With that addition you are negating all the work you did. And you should not inherit from map since MyMap is not behaviorally a map anymore. Make a simple utility method. – Esailija Feb 28 '13 at 14:04
  • @Esailija I am updating the input map and then finally putting input map elements in the current map. Have a look at the fiddle here - http://ideone.com/2BHYUr – Ravindra Gullapalli Feb 28 '13 at 14:07
0

Try this method. Works with a generic key type. Value type remains Integer as we are adding them.

public <K> void putAndAdd(Map<K, Integer> to,
        Map<? extends K, ? extends Integer> from) {
    for (Iterator<? extends Map.Entry<? extends K, ? extends Integer>> i = from
            .entrySet().iterator(); i.hasNext();) {
        Map.Entry<? extends K, ? extends Integer> e = i.next();
        if (to.get(e.getKey()) != null) {
            to.put(e.getKey(), to.get(e.getKey()) + e.getValue());
        } else {
            to.put(e.getKey(), e.getValue());
        }
    }
}