I'm trying to add different values for same key in a map and then store it in a list and code is below
public static void main(String[] args) {
Map<String, Object> mainMap = new HashMap<>();
List<Object> list = new ArrayList<>();
mainMap.put("1", "First");
for (int i = 1; i < 6; i++) {
Map<String, Object> childMap = new HashMap<>();
childMap.put("2", i);
mainMap.put("1", childMap.get("2"));
list.add(mainMap);
System.out.println("mainMap:" + mainMap);
}
System.out.println("list:" + list);
}
Actual output:
mainMap:{1=1}
mainMap:{1=2}
mainMap:{1=3}
mainMap:{1=4}
mainMap:{1=5}
list:[{1=5}, {1=5}, {1=5}, {1=5}, {1=5}]
Expected output:
list:[{1=1}, {1=2}, {1=3}, {1=4}, {1=5}]
Is it possible to achieve this using Map and if yes please guide me.
A Map instance replaces the old value if a value with the same key is put into it as a Map can not store duplicate keys. Since you are putting iteration values against the same key into the same instance of mainMap, the new value is replacing the old one. You need to assign a new instance to mainMap every time you put into it an iteration value using the same key. The following code will give you a hint to proceed:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Object> map;
List<Object> list = new ArrayList<Object>();
for (int i = 1; i < 6; i++) {
map = new HashMap<String, Object>();
map.put("1", i);
list.add(map);
}
System.out.println("list:" + list);
}
}
Output:
list:[{1=1}, {1=2}, {1=3}, {1=4}, {1=5}]
It would be not possible to achieve the desired result using Map. According to Java documentation:
An object that maps keys to values. A map cannot contain duplicate
keys; each key can map to at most one value.
https://docs.oracle.com/javase/8/docs/api/java/util/Map.html
As an alternative, you may try to store a List in the Map, like this:
public static void main(String[] args) {
Map<String, Object> mainMap = new HashMap<>();
List<Object> childList = new ArrayList<>();
mainMap.put("1", childList);
for (int i = 1; i < 6; i++) {
childList.add(i);
}
List<Object> list = new ArrayList<>();
list.add(mainMap);
System.out.println("list:" + list);
}
Output:
list:[{1=[1, 2, 3, 4, 5]}]
Related
I need to fill Map<String, Map<String, Integer>> with values. My code is as follows:
// tags, <types, prices>
Map<String, Map<String, String>> outter = new HashMap<>();
List<String> tags = new ArrayList<String>();
tags.add("1tag");
tags.add("2tag");
List<String> types = new ArrayList<String>();
types.add("paper");
types.add("metal");
List<String> prices = new ArrayList<String>();
prices.add("1.20");
prices.add("2.20");
for (int t = 0; t < tags.size(); t++) {
Map<String, String> inner = new HashMap<>();
for (int tp = 0; tp < types.size(); tp++) {
for (int p = 0; p < prices.size(); p++) {
inner.put(types.get(tp), prices.get(p));
}
}
outter.put(tags.get(t), inner);
}
System.out.println("filled outter:" + outter);
The result is:
filled outter:{2tag={paper=2.20, metal=2.20}, 1tag={paper=2.20, metal=2.20}}
The correct result I want is:
filled outter:{2tag={paper=1.20, paper=2.20, metal=1.20, metal=2.20}, 1tag={paper=1.20, paper=2.20, metal=1.20, metal=2.20}}
How to prevent overriding values and get correct result?
Help..
As reported by others Java's Map interface maps each key to a single value. If you want to assign multiple values to a single key, you can either do that manually (mapping to a List). Or use a library that already has that, like Guava's Multimap for your inner map.
That way you will have something like:
filled outter:{2tag={paper=[1.20, 2.20], metal=[1.20, 2.20]}, 1tag={paper=[1.20, 2.20], metal=[1.20, 2.20]}}
And you would define your map as:
Map<String, Multimap<String, String>> outter = new HashMap<>();
You have an example usage of Multimap here.
Because you can't set two keys inside a Map with the same name. You should create a ArrayList or something simular inside the outer Map.
I am trying to compare the Key value pairs of an hash map where the value order is not same as i am reading the map1 from one source and map2 from another source.
The keys will be same but the order list will be in a different order.
The comparison is resulting fail, which i need to fix it
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
public class TestClass {
private static Map<String, List<String>> tempMap;
private static Map<String, List<String>> tempMap1;
private static Map<String, List<String>> tempMap2;
private static Map<String, List<String>> tempMap3;
public static Map<String, List<String>> practiceMap(){
tempMap = new HashMap<String, List<String>>();
List<String> completeDateKey = new ArrayList<>();
List<String> statusKey = new ArrayList<String>();
List<String> completeDateValue = new ArrayList<String>();
List<String> statusValue = new ArrayList<String>();
ArrayList<String> key = new ArrayList<String>(Arrays.asList("Complete Date", "Status"));
ArrayList<String> completedate = new ArrayList<String>(Arrays.asList("", "11/15/2019"));
ArrayList<String> status = new ArrayList<String>(Arrays.asList("NEW", "CLOSE"));
completeDateKey.add(key.get(0));
statusKey.add(key.get(1));
completeDateValue.addAll(completedate);
statusValue.addAll(status);
tempMap.put(completeDateKey.toString(), completeDateValue);
tempMap.put(statusKey.toString(), statusValue);
return tempMap;
}
public static Map<String, List<String>> practiceMap1(){
tempMap1 = new HashMap<String, List<String>>();
List<String> completeDateKey = new ArrayList<>();
List<String> statusKey = new ArrayList<String>();
List<String> completeDateValue = new ArrayList<String>();
List<String> statusValue = new ArrayList<String>();
ArrayList<String> key = new ArrayList<String>(Arrays.asList("Complete Date", "Status"));
ArrayList<String> completedate = new ArrayList<String>(Arrays.asList("11/15/2019", ""));
ArrayList<String> status = new ArrayList<String>(Arrays.asList("CLOSE", "NEW"));
completeDateKey.add(key.get(0));
statusKey.add(key.get(1));
completeDateValue.addAll(completedate);
statusValue.addAll(status);
tempMap1.put(completeDateKey.toString(), completeDateValue);
tempMap1.put(statusKey.toString(), statusValue);
return tempMap1;
}
public static void comparisionTest() {
tempMap3 = new HashMap<String, List<String>>();
tempMap2 = new HashMap<String, List<String>>();
tempMap2 = practiceMap();
tempMap3 = practiceMap1();
System.out.println("map 1 is " + tempMap2);
System.out.println("map 2 is " + tempMap3);
int size = practiceMap().size();
System.out.println(size);
if(tempMap2.equals(tempMap3) == true) { System.out.println("Successful"); }
else { System.out.println("failed"); }
}
public static void main(String[] args) {
new TestClass().comparisionTest();
}
}
How can i fix this so my comparision is successful
What you are looking for is called data normalization (in a broad sense).
Meaning: when you want to compare data in meaningful ways, you have to ensure that all data you look at is "organized" the same way.
In your case: if "equal" means: the same pairs of keys, and same content (ignoring order), then you can easily normalized that, for example by:
sorting the hash keys (when you iterate the hash keys in lexicographical order, well, you have a defined order)
sorting the lists
You could either do that "on the fly" (within a Comparator implementation for example), or by explicitly copying your data into such "ordered" collections.
If your lists do not have duplicates in them you could use sets since sets of the same values compare equally without regard to order.
Set<String> set1 = new LinkedHashSet<>();
set1.add("Alpha");
set1.add("Beta");
set1.add("Gamma");
Set<String> set2 = new LinkedHashSet<>();
set2.add("Gamma");
set2.add("Beta");
set2.add("Alpha");
Map<String, Set<String>> map1 = Map.of("A", set1);
Map<String, Set<String>> map2 = Map.of("A", set2);
System.out.println(set1.equals(set2)); // true
System.out.println(map1.equals(map2)); // true
I have a List<Map<key,value>>. I want to remove it from the list if the key exist in List
For example:
Input: List<Map<a,1>,Map<b,2>,Map<c,3>> (here is a Map) , List<a,d,e>
Explanation: Since, key in map <a,1> exists in the List<a,d,e>, I want to remove Map from the List<Map<a,1>,Map<b,2>,Map<c,3>>
Output: List<Map<b,2>,Map<c,3>>
perhaps you could use java streams api, and do something like this:
public class Mapping {
public static void main(String args[])
{
List<Map<String,Integer>> db = new LinkedList<Map<String,Integer>>();
Map<String,Integer> item = new HashMap<String,Integer>();
item.put("a", 1);
item.put("b", 2);
item.put("c", 3);
db.add(item);
List<String> excludeList = Arrays.asList("a");
List<Map<String,Integer>> newDb = db.stream().map(sample->{
Map<String,Integer> newSample = new HashMap<String,Integer>(sample); //we do not mutate original elements
excludeList.forEach(key->newSample.remove(key));
return newSample;
}).collect(Collectors.toList());
System.out.println(db); //[{a=1, b=2, c=3
System.out.println(newDb); //[{b=2, c=3}]
}
}
in this fashion, you keep both original and new filtered lists
try this, if you want to check the exclude key with list of maps
public static void main(String[] args)
{
List<String> removeList = Arrays.asList("a","d","e");
List<Map<String, Integer>> maps = new ArrayList<>();
//Map1
Map<String, Integer> map1 = new HashMap<>();
map1.put("a", 1);
map1.put("b", 2);
map1.put("c", 3);
maps.add(map1);
//Map2
Map<String, Integer> map2 = new HashMap<>();
map2.put("e", 1);
map2.put("f", 2);
map2.put("g", 3);
maps.add(map2);
for(String string : removeList)
{
for(Map<String, Integer> eachMap: maps)
{
eachMap.remove(string);
}
}
System.out.println(maps);
}
I am trying to add a Key(String), Value(HashMap) to another HashMap. I somehow keep jumbling up the syntax and logic here. How do I do that? I have a kmap here initialized and then I want to add a key which is a string, and a value which is another HashMap<String, List<Integer>>)
These can be seen in the parameters below:
static HashMap<String, HashMap<String, List<Integer>>> kmap = new HashMap<String, HashMap<String, List<Integer>>>();
public synchronized static void AddMapToList_ofMAP_(HashMap<String, List<Integer>> value, String key) {
if (!kmap.containsKey(key)) {
kmap.put(key, new HashMap<String, List<Integer>>());
}
HashMap<String, List<Integer>> q = kmap.get(key);
q.put(key, value);
}
It's WAY simpler than you're making it seem. You don't need a separate method, just invoke the put(key, value) method on your kmap. Assuming you have a Map<String, List<Integer>> in a variable named value, it's just:
kmap.put(key, value);
That's all. Just one line.
In your parameters you have got a HashMap called value. You are then trying to add that to the HashMap inside the HashMap but the value in that needs to be a List of integers.
Fix:
static HashMap<String, HashMap<String, List<Integer>>> kmap = new HashMap<String, HashMap<String, List<Integer>>>();
public synchronized static void AddMapToList_ofMAP_(
List<Integer> value, String key) {
if (!kmap.containsKey(key)) {
kmap.put(key, new HashMap<String, List<Integer>>());
}
HashMap<String, List<Integer>> q = kmap.get(key);
q.put(key, value);
}
Also, a possible way to make this better is using an Object. I'm not sure how the code and what your putting in but an object could work.
I'm also seeing you get the HashMap by the key but you also put that key in the HashMap (The one inside), surely you could just have 1 HashMap there.
I'm not sure what exactly you are trying to achieve here. Here's what possibly you may want to do. Feel free to write more test cases and optimize the code. However this will give you a based structure to work on.
public class Stackoverflow {
static HashMap<String, HashMap<String, List<Integer>>> kmap = new HashMap<String, HashMap<String, List<Integer>>>();
public synchronized static void addIntegerToKmap(String kmapKey, String intMapKey, Integer value) {
if (!kmap.containsKey(kmapKey)) {
Map<String, List<Integer>> intMap = new HashMap<String, List<Integer>>();
HashMap<String, List<Integer>> stringListHashMap = new HashMap<String, List<Integer>>();
List<Integer> integerList = new ArrayList<Integer>();
integerList.add(value);
stringListHashMap.put(intMapKey, integerList);
kmap.put(kmapKey, stringListHashMap);
}
else {
HashMap<String, List<Integer>> stringListHashMap = kmap.get(kmapKey);
List<Integer> integerList = stringListHashMap.get(intMapKey);
if (integerList != null && !integerList.isEmpty()) {
integerList.add(value);
}
else {
integerList = new ArrayList<Integer>();
integerList.add(value);
stringListHashMap.put(intMapKey, integerList);
}
}
}
public static void main(String args[]) {
addIntegerToKmap("A", "A1", 1);
addIntegerToKmap("A", "A1", 2);
addIntegerToKmap("A", "A2", 12);
addIntegerToKmap("A", "A2", 22);
addIntegerToKmap("B", "B1", 1);
addIntegerToKmap("A", "A1", 3);
}
}
The logic is not clear but maybe you want this
q.put(key, value.get(key));
instead of this:
q.put(key, value);
I have a Map , but I want the values of the map to be of type ArrayList
Map m = new HashMap();
since the value of the Key 'A' would itself have multiple values eg. key 'A' has values 10,20,30 please advise how to achieve this, I have created the first step below
LinkedHashMap<String,List<String>> A = new LinkedHashMap<String,List<String>>();
please advise how to add the multiple values in the list next and store it along with the Map in put operation
If I understand the question correctly then this seems to be the right way to me, all you then need to do is either:
List<String> strings = new ArrayList<String>();
strings.add("10");
strings.add("20");
strings.add("30");
A.put(strings);
Or you can:
A.put(Arrays.asList("10", "20", "30"));
Like this -
LinkedHashMap<String,List<String>> A = new LinkedHashMap<String,List<String>>();
List<String> list = new ArrayList<String>();
list.add("10");
list.add("20");
list.add("30");
A.put("a", list);
Like :
List<String> list = new ArrayList<>();
list.add("abc");
list.add("xyz");
// ....
Map<String,List<String>> map = new HashMap<>();
map.put("Key", list);
as I know that, you can use Apache MultiValueMap. It meets your requirement.http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/MultiValueMap.html
Here is a program.
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
public class Test {
public static void main(String[] args) {
LinkedHashMap<String,List<String>> A = new LinkedHashMap<String,List<String>>();
List<String> list = new ArrayList<>();
list.add("1");
A.put("1", list);
//add new values
list = A.get("1");
if(list!=null){
list.add("2");
}else{
list = new ArrayList<String>();
list.add("2");
}
A.put("1", list);
}
}
You can replace List with TreeSet and if the all values are integer then it will be better to use Integer instead of String
Here in example taken Integer type while just replace it with String it will work fine as well.
public static void main(String[] args) {
LinkedHashMap<String, TreeSet<Integer>> lhm = new LinkedHashMap<>();
TreeSet<Integer> set = new TreeSet<>();
set.add(20);
set.add(10);
set.add(30);
set.add(50);
set.add(70);
set.add(60);
set.add(90);
set.addAll(Arrays.asList(22,33,44,55));
lhm.put("A",set);
System.out.println(lhm);
}