yogsma
yogsma

Reputation: 10586

Hashmap comparison

I have two hashmaps. This is just example of 2 hashmaps, there can be n hashmaps.

They look like this

HashMap A = [(a, 23),(b,25),(c,43),(d,34)]
HashMap B = [(a, 32),(b,52),(d,55)]

Now I want to compare these hashmaps in such a way so that I can put the missing key of 'c' into HashMap B with value as 0.

How can I do that? Remember there can be n HashMaps.

Upvotes: 1

Views: 4254

Answers (5)

Carl
Carl

Reputation: 7544

Set<Key> keys = new HashSet<Key>(/* if you have any perspective on size, could put it here */);
for (Map<Key, ?> map : n-maps) keys.addAll(map.keySet());
for (Map<Key, ?> map : n-maps) for (Key k : keys) if(!map.containsKey(k)) map.put(k, defaultObject);

where n-maps is an Iterable or array of your maps, and the defaultObject is whatever default you want to put in there.

There are some sensible optimization routes, like comparing the size of the keys set to that of the target map, which would allow you to branch into a couple of sensible categories: the same size, very close to 0 or keys.size(), or otherwise.

Upvotes: 0

maerics
maerics

Reputation: 156434

Let's call the "target" HashMap the one that will get the missing keys and "sources" each of the others. For each key in each source, if the target does not contain the key then associate the zero with that key in the target:

for (Map<String,Number> source : sources) {
  for (String key : source.keySet() ) {
    if (!target.containsKey(key)) {
      target.put(key, 0);
    }
  }
}

Now if you want to ensure that all maps have all keys from all other maps then you should first compute the entire set of keys and add the missing ones to each map:

Set<String> allKeys = new HashSet<String>();
for (Map<String,Number> map : allHashMaps) {
  allKeys.addAll(map.keySet());
}
for (Map<String,Number> map : allHashMaps) {
  for (String key : allKeys) {
    if (!map.containsKey(key)) {
      map.put(key, 0);
    }
  }
}

Both solutions perform at O(n*k) where n is the number of maps and k is the average number of keys in each map.

Upvotes: 2

ColinD
ColinD

Reputation: 110046

Guava has something that could help you here:

Map<K, V> a = ...
Map<K, V> b = ...
MapDifference<K, V> difference = Maps.difference(a, b);

A MapDifference then allows you to check various things about the difference of the two maps, such as what entries the left Map has that the right doesn't and vice versa.

If you wanted to make sure that there aren't any entries in map a that b doesn't have, you could do something like this:

b.putAll(difference.entriesOnlyOnLeft());

How you handle a series of maps depends on exactly what you need to do with them, which you didn't really explain... but you could just loop through them doing the above with every pair of maps to ensure that the last map has at least every entry that is in every other map, for example.

Upvotes: 3

Amir Raminfar
Amir Raminfar

Reputation: 34149

You can do A.keySet().removeAll(B.keySet()) which will give you all the items in A that are not in B

Upvotes: 1

C. K. Young
C. K. Young

Reputation: 223013

public static <T> void mergeKeys(Map<T, Integer> target, Map<T, ?>... sources) {
    Set<T> newKeys = new HashSet<T>();
    for (Map<T, ?> source : sources)
        newKeys.addAll(source.keySet());
    newKeys.removeAll(target.keySet());
    for (T key : newKeys)
        target.put(key, 0);
}

Upvotes: 0

Related Questions