Reputation: 10586
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
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
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
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
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
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