Comparing two hash-maps and printing intersections - java

I have two hash maps: one contains an Integer key and String value.
The other contains an Integer key and float value.
Code
Map<Integer,String> mapA = new HashMap<>();
mapA.put(1, "AS");
mapA.put(2, "Wf");
Map<Integer,Float> mapB = new HashMap<>();
mapB.put(2, 5.0f);
mapB.put(3, 9.0f);
My question is how to compare the two hash maps using the integer key value? I want to print the bitmap value when the key values are the same.

You can just iterate on the keys of mapA and check if it is present in mapB then add the value to a third mapC for example.
Map<String, float> mapC = new HashMap<String, float>();
for (Integer key : mapA.keySet()) {
if (mapB.containsKey(key)) {
mapC.put(mapA.get(key), mapB.get(key));
}
}

Compare keys in two map by using mapB iterator.
Iterator<Entry<Integer, Float>> iterator = mapB.entrySet().iterator();
while(iterator.hasNext()) {
Entry<Integer, Float> entry = iterator.next();
Integer integer = entry.getKey();
if(mapA.containsKey(integer)) {
System.out.println("Float Value : " + entry.getValue());
}
}

If you are allowed to modify mapB, then the solution is as simple as mapB.keySet().retainAll(mapA.keySet());.
This will only leave those entries in mapB that have a corresponding key in mapA, because the set returned by keySet() is backed by the map itself, any changes made to it will be reflected to the map.

yes i got solution...
if(mapB.containsKey(position)){
Log.e("bucky",mapB.get(position));}
position means integer value.

With Java 8 Streams API:
Map<Integer, Object> matchInBothMaps = mapA
.entrySet()
.stream()
.filter(map -> mapB.containsKey(map.getKey()))
.collect(Collectors.toMap(map -> map.getKey(),
map -> map.getValue()));
System.out.println(matchInBothMaps);

Related

I want to compare the each value in a java map with another value

If a value matches with another value then, i want to get the key,value pair corresponding to that value into a new map and values that doesn't match i.e unique key,value pairs into another map.
Eg:
Map<String,Double> map = new HashMap<String,Double>();
map.put("First",123.12345); //data1
map.put("Second",234.3456); //data2
map.put("Third",576.9876); //data3
map.put("Fourth",123.12345);//data4
map.put("Fifth",234.3456); //data5
map.put("Sixth",999.8888); //data6
map.put("Seventh",677.4578); //data7
Now here (data1 and data4) values (data2 and data5) and match and i want to store these (key,value) pairs in a new Map
Similarly data3, data and data7 have unique values and i want to store these (key,value) pairs in another new Map.
Any help is appreciated.
Thanks in advance.
You grouping by the map value and collect those entry with same value into a Map.
Map<Double, Map<String, Double>> result =
map.entrySet().stream()
.collect(groupingBy(Entry::getValue, toMap(Entry::getKey, Entry::getValue)));
This will give you result like:
{
123.12345 -> {
First -> 123.12345,
Fourth -> 123.12345
},
234.3456 -> ...
}
In java 7:
Map<Double, Map<String, Double>> result = new HashMap<>();
for (Entry<String, Double> mapping : map.entrySet()) {
Double value = mapping.getValue();
if (!result.containsKey(value)) {
result.put(value, new HashMap<>());
}
// Add new pair to map
result.get(value).put(mapping.getKey(), value);
}

HashMap Key Comparison and return values in JAVA

I want to compare keys of two different hash maps say
Map<String, Float> map1 = new HashMap<>();
Map<String, Float> map2 = new HashMap<>();
map1:
<org.openjdk.jmh.samples.JMHSortBenchmark.collectionsSort,6691.679>
<org.openjdk.jmh.samples.JMHSortBenchmark.abcdSort,5151.45>
<org.openjdk.jmh.samples.JMHSortBenchmark.saasSort,5454.54>
<org.openjdk.jmh.samples.JMHSortBenchmark.xyzSort,888.22>
map2:
<org.openjdk.jmh.samples.JMHSortBenchmark.xyzSort,7448.362>
<org.openjdk.jmh.samples.JMHSortBenchmark.abcdSort,951.5>
<org.openjdk.jmh.samples.JMHSortBenchmark.lmnSort,4454.54>
And if they match eg., "org.openjdk.jmh.samples.JMHSortBenchmark.xyzSort" so I want to return the <Key,Value> pair of both map1 and map2 i.e., it must return
org.openjdk.jmh.samples.JMHSortBenchmark.xyzSort,888.22
org.openjdk.jmh.samples.JMHSortBenchmark.xyzSort,7448.362
org.openjdk.jmh.samples.JMHSortBenchmark.abcdSort,5151.45
org.openjdk.jmh.samples.JMHSortBenchmark.abcdSort,951.5
because I want to process the difference between their values and compare them i.e., 888.2 in map1 and 7448.362 in map2 thereby logging the difference to a csv file.
I used the following code:
for (Entry<String, Float> entry: map1.entrySet()) {
if (map2.containsKey(entry.getKey())) {
System.out.println("The matched value is" + entry.getValue() +"and Key is"+ entry.getKey());
}
}
but this could return only the values of map1 and not map2.
I have made a working solution for you.
static void test11()
{
HashMap<String, Float> map1 = new HashMap<>();
HashMap<String, Float> map2 = new HashMap<>();
map1.put("org.openjdk.jmh.samples.JMHSortBenchmark.collectionsSort",(float) 6691.679);
map1.put("org.openjdk.jmh.samples.JMHSortBenchmark.abcdSort1",(float) 5151.45);
map1.put("org.openjdk.jmh.samples.JMHSortBenchmark.saasSort",(float) 5454.54);
map1.put("org.openjdk.jmh.samples.JMHSortBenchmark.xyzSort",(float) 888.22);
map2.put("org.openjdk.jmh.samples.JMHSortBenchmark.xyzSort", (float) 7448.362);
map2.put("org.openjdk.jmh.samples.JMHSortBenchmark.abcdSort", (float) 951.5);
map2.put("org.openjdk.jmh.samples.JMHSortBenchmark.lmnSort", (float) 4454.54);
for(String key: map1.keySet())
{
// use key to search 2nd list, will be null if no matching key found
Float map2data = map2.get(key);
if (null == map2data)
{
// Current key not found
}
else
{
Float map1data = map1.get(key);
// You can do you operations here with matching keys data here
}
}
}
Hope this will help. :-)
I would do it like this:
map1.keySet().retainAll(map2.keySet());
The keySet() method will give you a set view (!) on the keys of the map. retainAll() will only keep the elements in that set that are keys in map2, too. If you want to keep all values of map1 you may want to make a copy first.

What is the best practices to merge two maps

How can I add a new map to existing map. The maps have the same type Map<String, Integer>. If the key from new map exists in the old map the values should be added.
Map<String, Integer> oldMap = new TreeMap<>();
Map<String, Integer> newMap = new TreeMap<>();
//Data added
//Now what is the best way to iterate these maps to add the values from both?
By add, I assume you want to add the integer values, not create a Map<String, List<Integer>>.
Before java 7, you'll have to iterate as #laune showed (+1 to him). Otherwise with java 8, there is a merge method on Map. So you could do it like this:
Map<String, Integer> oldMap = new TreeMap<>();
Map<String, Integer> newMap = new TreeMap<>();
oldMap.put("1", 10);
oldMap.put("2", 5);
newMap.put("1", 7);
oldMap.forEach((k, v) -> newMap.merge(k, v, (a, b) -> a + b));
System.out.println(newMap); //{1=17, 2=5}
What it does is that for each key-value pair, it merges the key (if it's not yet in newMap, it simply creates a new key-value pair, otherwise it updates the previous value hold by the existing key by adding the two Integers)
Also maybe you should consider using a Map<String, Long> to avoid overflow when adding two integers.
for( Map.Entry<String,Integer> entry: newMap.entrySet() ) {
// get key and value from newMap and insert/add to oldMap
Integer oldVal = oldMap.get( entry.getKey() );
if( oldVal == null ){
oldVal = entry.getValue();
} else {
oldVal += entry.getValue();
}
newMap.put( entry.getKey(), oldVal );
}
Hope that this is what you meant

Join two maps by key

I have two maps:
Map<Integer, String> mapOne = {(1,"a"), (2, "b")};
Map<Integer, Double> mapTwo = {(1,10.0), (2,20.0)};
and I want to combine this maps into one by Integer value, so the result map is
Map<String, Double> mapResult = {("a",10.0), ("b",20.0)};
Is there any way to do this easier than iterate over entry set?
Assuming that the keys of the two maps match and that the maps have the same number of entries, with Java 8 you can write it in one line with:
Map<String, Double> map = mapOne.entrySet().stream()
.collect(toMap(e -> e.getValue(),
e -> mapTwo.get(e.getKey())));
So you start from the first map and create a new map where the keys are the values of mapOne and the values are the corresponding values in mapTwo.
Technically this is somewhat equivalent to iterating over the entry set of the first map though.
Note: requires import static java.util.stream.Collectors.toMap;
Looks like only iteration:
#Test
public void testCollection() {
Map<Integer, String> mapOne = new HashMap<Integer, String>();
mapOne.put(1, "a");
mapOne.put(2, "b");
Map<Integer, Double> mapTwo = new HashMap<Integer, Double>();
mapTwo.put(1, 10.0);
mapTwo.put(2, 20.0);
Map<String, Double> mapResult = new HashMap<String, Double>();
Set<Integer> keySet = mapOne.keySet();
keySet.retainAll(mapTwo.keySet());
for (Integer value : keySet) {
mapResult.put(mapOne.get(value), mapTwo.get(value));
}
System.out.println(mapResult);
}
If the maps were the same type, you could use a putAll(), but since you are changing the key value pairs, it looks like you are going to have to iterate over each integer, get() from each map, then put(mapOneVal,mapTwoVal)
for(int i=0;i<max;i++){
String key = mapOne.get(i);
Double val = maptwo.get(i);
if(key!=null && val!=null)
map3.put(key,val);
}

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);
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.
Java 8 solution using Map#merge
As of java-8 you can use Map#merge(K key, V value, BiFunction remappingFunction) which merges a value into the Map using remappingFunction in case the key is already found in the Map you want to put the pair into.
// using lambda
newMap.forEach((key, value) -> map.merge(key, value, (oldValue, newValue) -> oldValue));
// using for-loop
for (Map.Entry<Integer, String> entry: newMap.entrySet()) {
map.merge(entry.getKey(), entry.getValue(), (oldValue, newValue) -> oldValue);
}
The code iterates the newMap entries (key and value) and each one is merged into map through the method merge. The remappingFunction is triggered in case of duplicated key and in that case it says that the former (original) oldValue value will be used and not rewritten.
With this solution, you don't need a temporary Map.
Let's have an example of merging newMap entries into map and keeping the original values in case of the duplicated antry.
Map<Integer, String> newMap = new HashMap<>();
newMap.put(2, "EVIL VALUE"); // this will NOT be merged into
newMap.put(4, "four"); // this WILL be merged into
newMap.put(5, "five"); // this WILL be merged into
Map<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
newMap.forEach((k, v) -> map.merge(k, v, (oldValue, newValue) -> oldValue));
map.forEach((k, v) -> System.out.println(k + " " + v));
1 one
2 two
3 three
4 four
5 five
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.
As others have said, you can use putIfAbsent. Iterate over each entry in the map that you want to insert, and invoke this method on the original map:
mapToInsert.forEach(originalMap::putIfAbsent);

Categories