How to compare two Hash Maps in Java - java

Hi I am working with HashMap in java and i have a scenario where i have to compare 2 HashMaps
HashMap1:
Key: BOF Value: SAPF
Key: BOM Value: SAPM
Key: BOL Value: SAPL
HashMap2:
Key: BOF Value: Data1
Key: BOL Value: Data2
And after comparing these two hashmaps my resulting hashmap will contain the Key as a Value of First HashMap1 and Value as a Value of second HashMap2.
HashMap3:
Key: SAPF Value: Data1
Key: SAPL Value: Data2

Just iterate on the keys of HashMap1, and for each key, check if it's present in HashMap2.
If it's present, add the values to HashMap3 :
final Map<String, String> hm1 = new HashMap<String, String>();
hm1.put("BOF", "SAPF");
hm1.put("BOM", "SAPM");
hm1.put("BOL", "SAPL");
final Map<String, String> hm2 = new HashMap<String, String>();
hm2.put("BOF", "Data1");
hm2.put("BOL", "Data2");
final Map<String, String> hm3 = new HashMap<String, String>();
for (final String key : hm1.keySet()) {
if (hm2.containsKey(key)) {
hm3.put(hm1.get(key), hm2.get(key));
}
}

Iterate over the keys of the first map and put the values in your new map, if the second map has a value for the same key.
Map map3 = new HashMap();
for (Object key : map1.keySet()) {
Object value2 = map2.get(key);
if (value2 != null) {
Object value1 = map1.get(key);
map3.put(value1, value2);
}
}

HashMap has an method called entrySet() that returns an object that represents the content of the map as a set of key-value pairs.
public Set<Map.Entry<K,V>> entrySet()
You should iterate through that set using the keys to look up in the second map and then putting the results in the 'result set'.
I assume you have a established that the values in the first set will be unique OR you don't mind that entries might get overwritten in the output.
Notice that the iterator moves through the set in an unspecified order so if there are overwrites this method won't guarantee which values overwrite which other values.

You can use the keySets of both maps to intersect them using:
boolean retainAll(Collection<?> c)
and then iterate using that intersection over the tho maps building your solution.

Related

comparing values of two different hashmaps based on their key in java

I have two different hashmaps. Now I need to compare the hashmaps based on their keys.Like,
HashMap1:
Key: BOF Value: SAPF,754
Key: BOM Value: SAPM,456
Key: BOL Value: SAPL,987
HashMap2:
Key: LOF Value: YTR,654
Key: BOL Value: UHG,732
Now I want to compare all those entries in the hashmaps whose 'key's are same and return the difference between the second index of 'values' String[]
Like here it should return:
Key: BOL Value: SAPL,255
(as 987-732=255)
How to do it?
map.keySet() will return set of keys in map. Then you have to get value with this key from both map and find the difference.
Map<String, String[]> mp1 = //
Map<String, String[]> mp2 = //
Map<String, List<String>> res = new HashMap<>();
for (String key : mp1.keySet()) {
int val1 = Integer.valueOf(mp1.get(key)[1]);
int val2 = Integer.valueOf(mp2.get(key)[1]);
List<String> resVal = new ArrayList<>();
resVal.add(mp1.get(key)[0]);
resVal.add(String.valueOf(val1-val2));
res.put(key, resVal);
}
return res;
One more thing, you have check for existence. Otherwise you will get NullPointerException

Identify the Key-Value pair having duplicate values

I have a multimap like below:
{20014=[13123], 20013=[45451, 13123]}
where the keys and values are in String
If there is any duplicate in the value from other key, I have to print that key-value pair. In this case, it will be Key-20013,Value-13123.
How to achieve this?
I checked this link but not getting how to get the duplicate pair.
It could be done like this:
// Initialize my multimap
Multimap<String, String> multimap = ArrayListMultimap.create();
multimap.put("20014", "13123");
multimap.put("20013", "45451");
multimap.put("20013", "13123");
// Set in which we store the values to know if they exist already
Set<String> allValues = new HashSet<>();
// Convert the multimap into a Map
Map<String, Collection<String>> map = multimap.asMap();
// Iterate over the existing entries
for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
String key = entry.getKey();
Collection<String> values = entry.getValue();
// Iterate over the existing values for a given key
for (String value : values) {
// Check if the value has already been defined if so print a log message
if (!allValues.add(value)) {
System.out.println(String.format("Key-%s,Value-%s", key, value));
}
}
}
Output:
Key-20013,Value-13123
You can invert your multimap and, viewed as a map, iterate through its entries:
Multimap<String, String> inverse = Multimaps.invertFrom(multimap, HashMultimap.create());
for (Map.Entry<String, Collection<String>> entry : inverse.asMap().entrySet()) {
String value = entry.getKey();
Iterator<String> keysIterator = entry.getValue().iterator();
assert keysIterator.hasNext() : "there is always at least one key";
keysIterator.next(); // skip first key
while (keysIterator.hasNext()) { // each additional key is a duplicate
String key = keysIterator.next();
System.out.println(String.format("Key-%s,Value-%s", key, value));
}
}
Output:
Key-20013,Value-13123
If you are using an ImmutableMultimap then instead of Multimaps.invertFrom(Multimap, M) you can simply use ImmutableMultimap.inverse():
ImmutableMultimap<String, String> inverse = multimap.inverse();
If you simply want a map of duplicated values to their respective keys then you can use Maps.filterValues(Map, Predicate):
Map<String, Collection<String>> keysByDuplicatedValue = Maps.filterValues(inverse.asMap(),
keys -> keys.size() > 1);
Which will give you a map like below:
{13123=[20014, 20013]}

Compare the Two hashMaps and update the HashMap

class Student_Details{
String name;
int rollNumber;
String address;
// setter and getter of above data members
}
HashMap<String,Collection<Student_Details>> oldData;
HashMap<String,Collection<Student_Details>> newData;
lets say the value in HashMAp oldData is:
abc:[{sam,12,newyork},{mike,15,gotham}]
xyz:[{riphunter,32,new york}]
Hashmap newData contains:
abc:[{sam,12,newyork},{mike,17,London},{john,36,boston]
uvw:[{rip,39,boston}]
Things to do:
1)if key of newData is not present in oldData then add the key value to the oldData
2)if key of newData present in oldData then update the content of the Collection where name should not change .for example the final map(oldData)for above example should have following contents
abc:[{sam,12,newyork},{mike,17,London},{john,36,boston}]
xyz:[{riphunter,32,new york}]
uvw:[{rip,39,boston}]
Please help me with the solution...Thank you
You can use putAll() to achieve
Copies all of the mappings from the specified map to this map. These mappings will replace any mappings that this map had for any of the keys currently in the specified map.
I wrote an example here, I use map1 and map2 to simulate your oldData and newData.
putAll() is a wrap for put method which loops put action. Here's the explanation of put()
Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.
Therefore, if key exist, it will update value, otherwise it stores the new key and new value
Map<String, String> map1 = new HashMap<>();
Map<String, String> map2 = new HashMap<>();
map1.put("a", "1");
map1.put("b", "2");
map1.put("c", "3");
map2.put("a", "10");
map2.put("d", "4");
Map<String, String> temp = new HashMap<>();
temp.putAll(map1);
temp.putAll(map2);
temp.forEach((k,v) -> System.out.println("Key:" + k + ", Value:" +v));
The output is:
Key:a, Value:10
Key:b, Value:2
Key:c, Value:3
Key:d, Value:4
First the key of the map should be the name of the student. Now
Then just do this for every new student
oldMap.put (newStudent.getName(), newStudent);
What it would do is to add the newStudent. If the student with this key doesn't exist then it would be added otherwise, this new value would replace the previous value since its a HashMap which doesn't support duplicate values

Finding Matching Keys and Values in a Map

In this problem, I have to find all matching key/value mappings within two maps and then return it into a new map, but I am running into some problems. My idea is to find all matching keys from the two maps, then use these keys to reference it to the values. If the values matched, I would put the key/value into the map. I am trying to find out why it just adds all the keys that are in common; it only add those keys if its corresponding values match too. Thanks.
The prompt:
Write a method intersect that takes two Maps of strings to integers as parameters and that returns a new map whose contents are the intersection of the two. The intersection of two maps is defined here as the set of keys and values that exist in both maps. So if some key K maps to value V in both the first and second map, include it in your result. If K does not exist as a key in both maps, or if K does not map to the same value V in both maps, exclude that pair from your result. For example, consider the following two maps:
{Janet=87, Logan=62, Whitaker=46, Alyssa=100, Stefanie=80, Jeff=88, Kim=52, Sylvia=95}
{Logan=62, Kim=52, Whitaker=52, Jeff=88, Stefanie=80, Brian=60, Lisa=83, Sylvia=87}
Calling your method on the preceding maps would return the following new map (the order of the key/value pairs does not matter):
{Logan=62, Stefanie=80, Jeff=88, Kim=52}
My code:
// we need to store the keys, then get the values in common, then put the key/map into map
public static Map<String, Integer> intersect(Map<String, Integer> first, Map<String, Integer> second) {
Map<String, Integer> output = new HashMap<String, Integer>(first); // combined output
Set<String> keyFirst = new HashSet<String>(); // stores all the keys for first
for (String key: first.keySet()) { // goes through each key in input
keyFirst.add(key); // adds all keys from first into keyFirst
}
// goes through each key in common and checks to see if they reference to the same value
Iterator<String> keyFirstItr = keyFirst.iterator();
while (keyFirstItr.hasNext()) {
String keyTemp = keyFirstItr.next();
if (first.get(keyTemp) == second.get(keyTemp)) { // If same key, same value mapped
output.put(keyTemp, first.get(keyTemp)); // add key value to map
}
}
return output;
}
You are putting all the values from first to output by passing it to the constructor.
Map<String, Integer> output = new HashMap<String, Integer>(first); // you are passing first to the constructor.
You don't need to create another Set, keySet() method returns set so the below lines not required.
Set<String> keyFirst = new HashSet<String>(); // stores all the keys for first
for (String key: first.keySet()) { // goes through each key in input
keyFirst.add(key); // adds all keys from first into keyFirst
}
Here's the correct implemetataion.
// we need to store the keys, then get the values in common, then put the key/map into map
public static Map<String, Integer> intersect(Map<String, Integer> first, Map<String, Integer> second) {
Map<String, Integer> output = new HashMap<String, Integer>(); // combined output
// goes through each key in common and checks to see if they reference to the same value
Iterator<String> keyFirstItr = first.keySet().iterator();
while (keyFirstItr.hasNext()) {
String keyTemp = keyFirstItr.next();
if (first.get(keyTemp).equals(second.get(keyTemp))) { // If same key, same value mapped
output.put(keyTemp, first.get(keyTemp)); // add key value to map
}
}
return output;
}
Simpler solution to this exercise is to skip iterator and use for loop as below. For every name in map1 we check if it exists in map2 and if the values are matching. Then the K, and V are added to the new map:
public static Map intersect(Map<String, Integer> map1, Map<String, Integer> map2){
Map<String, Integer> newMap = new HashMap<>();
for (String name : map1.keySet()){
if(map2.containsKey(name) && map1.get(name).equals(map2.get(name))){
newMap.put(name, map1.get(name));
}
}
return newMap;
}

Why result of combining two hashMap is not corecct?

I have two HashMap, first one has 3149 records and the second one 5440 records, when I combine them, the result size is smaller then 3149+5440. Why and how can i solve it?
Map<String,String> bigMap = new HashMap<String, String>();
bigMap.putAll(hashMap1);
bigMap.putAll(hashMap2);
int j = 0;
for (Map.Entry<String, String> entry : bigMap.entrySet()) {
System.out.println(j++);
}
I also cheched with this code to be sure if there is some common key.
for (Map.Entry<String, String> entry : readCsv(hashMap1).entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if(entry.getKey().equals(hashMap2).get(key))){
System.out.println(i++);
}
}
Your hashMap1 and hashMap probably have a number of same keys. That's why some entries are overridden by other entries with similar keys.
If you have the same keys in the maps, then this is to be expected. Keys must be unique in a map. If you put a value into the map with a key that already exists, then the existing value is overwritten.
To find the common keys you can do
Set<String> common = new HsahSet<String>(hashMap1.keySet());
common.retainAll(hashMap2.keySet());
System.out.println("Common Keys " + common);

Categories

Resources