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
Related
So I have this HashMap
HashMap<String, Integer> hm = new HashMap <String, Integer>();
And the contents of it:
Key: "Apricots" Value: 3
Key: "Kiwi" Value: 2
Key: "Apple" Value: 2
Key: "Orange" Value: 1
And I want the output to be where Apple precedes Kiwi alphabetically:
Key: "Apricots" Value: 3
Key: "Apple" Value: 2
Key: "Kiwi" Value: 2
Key: "Orange" Value: 1
Is it possible to sort this?
Your question has some ambiguity because the result you have mentioned, are not alphabetically sorted by key and ordering by value makes no sense.
However, seems like you want to order by only the first letter of the key (so Apple and Appricots become a tie) and if there's a tie, order by the value. Assuming this, I propose the following solution:
Map<String, Integer> map = new HashMap<>();
map.put("Apricots", 3);
map.put("Kiwi", 2);
map.put("Apple", 1);
map.put("Orange", 1);
List<Map.Entry<String, Integer>> list = map.entrySet().stream()
.sorted((e1, e2) -> {
// Compare only the first 2 letters
int res = e1.getKey().substring(0, 1).compareTo(e2.getKey().substring(0, 1));
if (res == 0) {
// If its a tie, compare values DESC
return e2.getValue().compareTo(e1.getValue());
}
return res;
})
.collect(Collectors.toList());
System.out.println(list);
Here we use a custom comparator to order the entries of the map.
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]}
I am trying to traverse a Hash map in decreasing order or in increasing order but I am not getting the proper output.
Here is my map:
Hashmap<String Integer> hm= new Hashmap<String,Integer>();
Here are my values:
Key Value
Hi 4
kumar 1
Hello 1
vivek 3
I am trying something like:
List<Integer> ValueList = new ArrayList<Integer>(hm.values());
ArrayList<String> keyList = new ArrayList<String>(hm.keySet());
Collections.sort(ValueList);
Collections.reverse(keyList);
Collections.reverse(ValueList);
and I want this something like:
Key Value
kumar 1
Hello 1
vivek 3
Hi 4
I recommend using the Apache Commons Collections ListOrderedMap. Here's the solution:
//Populate the map
Map<String, Integer> map = new HashMap<>();
map.put("Hi", 4);
map.put("kumar", 1);
map.put("Hello", 1);
map.put("vivek", 3);
//Sort the values
List<Integer> values = new ArrayList<Integer>(map.values());
Collections.sort(values);
int size = values.size();
Set<Entry<String, Integer>> entries = map.entrySet();
//Create a new ordered map
ListOrderedMap<String, Integer> orderedMap;
orderedMap = ListOrderedMap.listOrderedMap(new HashMap<String, Integer>(map));
for (int i = 0; i < size; i++) {
Integer value = values.get(i);
Iterator<Entry<String, Integer>> iter = entries.iterator();
while (iter.hasNext()) {
Entry<String, Integer> entry = iter.next();
if (value.equals(entry.getValue())) {
//Put all values at index i that match the value
orderedMap.put(i, entry.getKey(), value);
}
}
}
//Print the orderedMap key/value pairs
entries = orderedMap.entrySet();
for (Entry<String, Integer> entry : entries) {
final String key = entry.getKey();
final Integer value = entry.getValue();
System.out.println("key = " + key + ", value = " + value);
}
Output:
key = Hello, value = 1
key = kumar, value = 1
key = vivek, value = 3
key = Hi, value = 4
You can view a Map as a set of entries, where each entry has a key and a value. So what you want is a sorted list of entries. You can't just sort keys or values, as you would lose the association between the key and the value:
List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
entries.sort(Comparator.comparing(Map.Entry::getValue));
If you need to access these values often, you can avoid the sort by using a TreeMap object.
http://docs.oracle.com/javase/8/docs/api/java/util/TreeMap.html
This special Map can be used like a normal HashMap with the additional feature that it will sort your keys automatically using their Comparable, Equals and Hash methods (which you have to override)
If you define your own Key Class, you can make it so it will sort your values automatically.
If you don't need this performance boost, extracting the values then sorting them with Collections.sort works well too.
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.
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);