Populate Map<String, Map<String, Integer>> with values - java

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.

Related

android arraylist get hashmap position

I have an ArrayList HashMap like the one below.
ArrayList<HashMap<String, String>> mArrType = new ArrayList<>();
with the following values added into it
HashMap<String, String> map;
map = new HashMap<String, String>();
map.put("type", "TRIMMER");
map.put("request", "5");
map.put("actual", "0");
mArrType.add(map);
map = new HashMap<String, String>();
map.put("type", "HAND ROUTER");
map.put("request", "6");
map.put("actual", "0");
mArrType.add(map);
map = new HashMap<String, String>();
map.put("type", "AIR COMPRESSOR");
map.put("request", "6");
map.put("actual", "0");
mArrType.add(map);
Question is how can i get the position of a hashmap from arraylist. eg : hashmap with 'type' trimmer has a position 0 in arraylist, I want to retrieve the position value "0"
I'll write a small util method
private static int getTrimmerTypeMapPosition(ArrayList<HashMap<String, String>> mArrType) {
for (int i = 0; i < mArrType.size(); i++) {
HashMap<String, String> mp = mArrType.get(i);
if (mp.get("type").equals("TRIMMER")) {
return i;
}
}
return -1;
}
To make this method very generic, have "type" and "TRIMMER" as method params, so that you can just pass any key and value pairs to check with.
That's not efficiently possible with your data structure. You can either store the own position in each HashMap or loop through all entries and search for the one with the type you are looking for.
You can, of course, define another HashMap<String, Integer> which maps all your type strings to the corresponding ArrayList index.
Others answer is also correct, but you can do this thing using Java8 also.
E.g.:
int index = IntStream.range(0, mArrType.size()).
filter(i -> mArrType.get(i).get("type").equals("TRIMMER"))
.findFirst().getAsInt();

Can we loop over a map using size and for loop

I've the below code.
String[] guest1 = { "surfing", "yoga", "walking" };
String[] guest2 = { "wine", "relaxation", "beach" };
ArrayList<String> list1 = new ArrayList<>();
list1.add("museums");
list1.add("canals");
list1.add("nightlife");
list1.add("walking");
ArrayList<String> list2 = new ArrayList<>();
list2.add("beach");
list2.add("surfing");
list2.add("relaxation");
ArrayList<String> list3 = new ArrayList<>();
list3.add("surfing");
list3.add("nightlife");
list3.add("beach");
list3.add("food");
list3.add("wine");
list3.add("walking");
String[] sagres = { "beach", "surfing", "relaxation" };
String[] biarritz = { "surfing", "nightlife", "beach", "food", "wine", "walking" };
Map map = new HashMap<String, ArrayList<String>>();
map.put("amsterdam", list1);
map.put("sagres", list2);
map.put("biarritz", list3);
for (int i = 0; i < map.size(); i++) {
System.out.println(map.keySet());
}
Here I'm trying to get the key and the values by looping on the size.
I know that this can be done using
for (Object keys : map.keySet().toArray()) {
System.out.println(keys);
}
But I have to compare 2 values at a time and work accordingly. I want to know if I can use the size and loop.
Thanks
This code gets the entry set of the Map. It then iterates over that entire set and prints out the keys and values, separated by a comma and a tab character. Since entry.getValue() returns a List<String>, it needs to be converted to a String for concatenation.
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println(entry.getKey() + ", \t" + entry.getValue().toString());
}
Also, general practice says to use List instead of ArrayList when declaring a List. This way, it preserves polymorphism. Regarding the comparisons, you are unclear on what you are trying to compare, so I cannot really give an answer on that.
The iterator may fulfill a similar role as index.
Iterator<Map.Entry<String, ArrayList<String>> iter1 = map.entrySet().iterator();
Iterator<Map.Entry<String, ArrayList<String>> iter2 = map.entrySet().iterator();
while (iter1.hasNext() || iter2.hasNext()) {
...
if (iter1.hasNext()) {
entry1 = iter1.next();
}
}
By the way it is more conventional and less typing to write as follows:
List<String> list1 = new ArrayList<>();
Map<String, List<String>> map = new HashMap<>();
That is specify variables as interfaces, and leave the specific implementing class open. Ideal for method parameters too.

Iterate two arraylists and put key-value to map more elegantly

In my method for starters I make sure the two ArrayLists have the same size, otherwise I throw an exception. The solution I use to iterate two ArrayLists and put the key-value pair in a map works fine, but I also find it not very elegant or up to date.
In this method I am filling a map that will later be used with the Apache freemarker library.
Map<String, Object> map = new HashMap<String, Object>();
String placeHolder;
String value;
for (int i = 0; i < placeHolderList.size(); i++) {
placeHolder = placeHolderList.get(i);
value = valueList.get(i);
map.put(placeHolder, value);
}
What is a more elegant and efficient way to do this in Java 8?
Something like this could do the trick:
List<String> placeHolderList = Arrays.asList("key1", "key2");
List<Object> valueList = Arrays.asList("value1", "value2");
Map<String, Object> result = IntStream.range(0, placeHolderList.size())
.boxed()
.collect(toMap(placeHolderList::get, valueList::get));
System.out.println(result);
Output:
{key1=value1, key2=value2}
As stated in #NicolasFilotto answer you need to iterate over the indices but there is no need to box the index itself.
Map<String, Object> result = IntStream.range(0, placeHolderList.size())
.collect(HashMap::new,
(map, i) -> map.put(placeHolderList.get(i), valueList.get(i)),
Map::putAll);
If your not using java 8. then try this:
List<String> keyList = Arrays.asList("1", "2");
List<String> valList = Arrays.asList("one", "two");
Map<String, String> map = new HashMap<String, String>();
for (int i = 0; i < keyList.size(); i++) {
map.put(keyList.get(i), valList.get(i));
}
System.out.println(map);

I wanna store multiple map values in single key of Redis in my Java Code

Here Below, I'm having one list of HashMap's and I wanna store all of these map's in single key of redis but I'm not getting any method to store all these maps in single key. Please help me in this problem.
Jedis jedis = new Jedis("localhost");
List <HashMap<String, String>> listOfMaps = new ArrayList<HashMap<String, String>>();
listOfMaps.add(new HashMap<String,String>);
listOfMaps.add(new HashMap<String,String>);
listOfMaps.add(new HashMap<String,String>);
listOfMaps.add(new HashMap<String,String>);
.
.
.
and so on lets take upto 10 values
Now, I wanna store these maps in a key like this:
for(int i=0;i<listOfMaps.size();i++){
jedis.hmset("mykey",listofMaps[i]);
}
But in his case hmset overwrites all older values to write new values.
Please tell me any alternative to store all these map values in single key mykey.
You can use Multimap object provided by Redisson framework. It allows to store multiple values per map key as list or set. Here is the example:
RMultimap<String, Integer> multimap = redisson.getListMultimap("myMultimap");
for (int i = 0; i < 10; i++) {
myMultimap.put("someKey", i);
}
// returns Redis list object
RList list = myMultimap.get("someKey");
You can use something like below
public static void main(String[] args) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> valSetOne = new ArrayList<String>();
valSetOne.add("ABC");
valSetOne.add("BCD");
valSetOne.add("DEF");
List<String> valSetTwo = new ArrayList<String>();
valSetTwo.add("CBA");
valSetTwo.add("DCB");
map.put("FirstKey", valSetOne);
map.put("SecondKey", valSetTwo);
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
String key = entry.getKey();
List<String> values = entry.getValue();
System.out.println("Value of " + key + " is " + values);
}
}

How to remove duplicate values from a HashMap

I don't know how can best describe my problem but here it is, I'm trying to remove the same names(values) from HashMap<String, String> map = new HashMap<String, String>();
for example if this map contain names like
map.put("Vivaldi","Antonio");
map.put("Belucci", "Monica");
map.put("Gudini", "Harry");
map.put("Verdo", "Dhuzeppe");
map.put("Maracci", "Bruno");
map.put("Carleone", "Vito");
map.put("Bracco", "Luka");
map.put("Stradivari", "Antonio");
I want to remove all entries with the value "Antonio" from it by using method removeTheFirstNameDuplicates, I looked in Google for a couple of days and all examples are close to what I want but not really what I need.
My thoughts are, I need something that will check a map and if it contains the same values in it then remove the duplicate. But how can I do this?
You can do it with the following method which only iterates over the map once:
private static void removeTheFirstNameDuplicates(final Map<String, String> map) {
final Iterator<Entry<String, String>> iter = map.entrySet().iterator();
final HashSet<String> valueSet = new HashSet<String>();
while (iter.hasNext()) {
final Entry<String, String> next = iter.next();
if (!valueSet.add(next.getValue())) {
iter.remove();
}
}
}
The add() method on HashSet will return false if a value has already been added to the set. The method above uses this to detect that a duplicate has been found and then removes the duplicate from the HashMap by using the remove() method on the iterator.
It is worth noting that, depending on the Map implementation you use, the iteration order may not be guaranteed so which duplicate you remove is also not guaranteed.
If you were to use a TreeMap rather than a HashMap you would be certain to iterate over the map alphabetically by key e.g. Berluccio, Bracco, Carleone … Verdo. You would then always keep Stradivari and remove Vivaldi.
Try this
ArrayList<String> values = new ArrayList<String>();
ArrayList<String> keys = new ArrayList<String>();
java.util.Iterator<Entry<String, String>> iterate = map.entrySet()
.iterator();
while (iterate.hasNext()) {
Entry mapEntry = iterate.next();
String key = (String) mapEntry.getKey();
String value = (String) mapEntry.getValue();
values.add(value);
keys.add(key);
}
for (int i = 0; i < values.size(); i++) {
if (Collections.frequency(values, values.get(i)) > 1) {
map.remove(keys.get(i));
}
}
System.out.println(map.toString());

Categories

Resources