Itetrate Map<String, Map<String, String>> using java - java

I have a hashmap used to store the platform details
I need to iterate Map<String, Map<String, String>> finalmapWin8
and get the values and keys of mapWin8
values 33,8 and key BrowserType.CHROME, BrowserType.FIREFOX and BrowserType.IE
Also i want to get the key of 'finalmapWin8' "WIN8_1"
How can i iterate Map<String, Map<String, String>> finalmapWin8
static Map<String, Map<String, String>> finalmapWin8 = new HashMap<Platform, Map<String, String>>();
public static final Map<String, String> mapWin8 = new HashMap<String, String>();
static {
mapWin8.put(BrowserType.CHROME, "33");
mapWin8.put(BrowserType.FIREFOX, "33");
mapWin8.put(BrowserType.IE, "8");
}
static {
finalmapWin8.put("WIN8_1", mapWin8);
}

iteration for Map is the same. since your value for your map is also a Map then you just need another iteration to iterate through it.
for(String s: finalmapWin8.keySet()){
System.out.println(s + " : ");
for(Entry<String, String> entry : finalmapWin8.get(s).entrySet()){
System.out.println(entry);
}
}

You can use a for loop for loop for Map of type Map.Entry<String, Map<String, String>> ... well, that's it.. See the code snippet below -
import java.util.HashMap;
import java.util.Map;
public class Test {
static Map<String, Map<String, String>> finalmapWin8 = new HashMap<String, Map<String,String>>();
public static final Map<String, String> mapWin8 = new HashMap<String, String>();
static {
mapWin8.put("CHROME", "33");
mapWin8.put("FIREFOX", "33");
mapWin8.put("IE", "8");
}
static {
finalmapWin8.put("WIN8_1", mapWin8);
}
public static void main(String[] args) {
for(Map.Entry<String, Map<String, String>> entry : finalmapWin8.entrySet()) {
System.out.println(entry.getValue());
}
}
}

// get the keysets or outer map and then again run a secound loop for inner map.
for (Map.Entry<String, Map<String, String>> entry : firstMap) {
system.out.println("entry="+entry );
}
Refer to How to efficiently iterate over each Entry in a Map?

You can use below code for iterating through HashMap
for (Map.Entry<String, Map<String, String>> entry : finalmapWin8.entrySet()) {
System.out.println("Key:"+entry.getKey());
for (Map.Entry<String, String> entry1 : mapWin8.entrySet()) {
System.out.println("Keys in Second:"+ entry1.getKey()+" Values:"+ entry1.getValue());
}
}

Related

Map<String, Map<String, String>> may not contain values of type String

I am not able get the code to go to else block. The code always goes inside if block. Is there a way to validate the value of a Map<String, Map<String,String>>.
I get compile warning Map<String, Map<String, String>> may not contain values of type String.
Could anyone please tell me how to validate this?
public class TestClass {
Map<String, String> map = new HashMap<String, String>();
Map<String, Map<String, String>> val= new HashMap<String, Map<String, String>>();
public void setData() {
map = new HashMap<String, String>();
map.put("10", "1000");
map.put("11", "alphabet");
map.put("12", "1002");
map.put("13", "1003");
val.put("1", map);
val.put("2", map);
val.put("3", map);
val.put("4", map);
}
public void showData() {
if (!this.val.containsValue("alphabet")) {
System.out.println("inside if ");
} else {
System.out.println("else");
}
}
public static void main(String args[]) {
TestClass obj = new TestClass();
obj.setData();
obj.showData();
}
}

How do i acess a nested hash map value that i have return from another class ? Java

I am new to hash mapping and I was trying to created a nested hash map on one side of the class and create another class to call it out, so here's how my code looks like
public class Hash {
private HashMap<String, HashMap<String, String>> wow = new HashMap<String, HashMap<String, String>>();
public void SetHash(){
wow.put("key", new HashMap<String, Object>());
wow.get("key").put("key2", "val2");
}
public HashMap GetMap(){
return wow;
}
}
And on the other class which is the main class it will be like this:
public static void main(String[] args) {
Hash h = new Hash();
h.SetHash();
System.out.println(h.GetMap.get("key").get("key2"));
}
But when I place the second get, there's an error, so I am not sure if this is possible or if I should actually place the hash directly at the main class.
GetMap is a method, not an attribute, so you have to refer it with parenthesis ():
h.GetMap().get("key")
Now, second error. Your Map<String, Map<String, String> named wow contains a values that are objects of the type Map<String, String> so, before the get, you need get the map:
Map<String, String> m = (HashMap<String, String>) h.GetMap().get("key");
And then you can print it:
System.out.println(m.get("key2"));
if you want an ONELINER (is not really clear, but check explanation in comments):
System.out.println(((HashMap<String, String>) h.GetMap().get("key")).get("key2"));
// ↑ casting parenthesis ↑ (
// ↑ this say group IS a map and allow get() ↑
// ↑ system.out.println parenthesis ↑
NOTE: change also this declaration
wow.put("key", new HashMap<String, Object>());
By
wow.put("key", new HashMap<String, String>());
FINAL CODE:
public class Q37066776 {
public static void main(String[] args) {
Hash h = new Hash();
h.SetHash();
Map<String, String> m = (HashMap<String, String>) h.GetMap().get("key");
System.out.println(m.get("key2"));
}
}
class Hash {
private HashMap<String, HashMap<String, String>> wow = new HashMap<String, HashMap<String, String>>();
public void SetHash() {
wow.put("key", new HashMap<String, String>());
wow.get("key").put("key2", "val2");
}
public HashMap GetMap() {
return wow;
}
}
WORKING ONLINE DEMO
but you can always
Do it better! :=)
As pointed by Andrew
you can change return of the method,
But also many other things like:
using less concrete objects (Map instead of HashMap)
follow conventions (GetMap() would be getMap())
Make Hash a static class with static block
If I had to rewrite your code, my result would be like this:
public class Q37066776 {
public static void main(String[] args) {
System.out.println(Hash.getMap().get("key").get("key2"));
}
}
class Hash {
private static Map<String, Map<String, String>> wow = new HashMap<String, Map<String, String>>();
static {
wow.put("key", new HashMap<String, String>());
wow.get("key").put("key2", "val2");
}
public static Map<String, Map<String, String>> getMap() {
return wow;
}
}
You have 3 errors:
GetMap is a method - you need to write GetMap().
you declared the inner Map as HashMap<String, String> - you cannot initialize the inner map to: wow.put("key", new HashMap<String, Object>());
Change it to wow.put("key", new HashMap<String, String>());
In order to access the inner map from the main - you must declare the returned value of GetMap to be Map<String, HashMap<String, String>> instead of just raw type. Otherwise, the outer class won't know that the outer map value is also a hash map.
Instead of using nested maps, you should use google's Guava Table:
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Table.html

How to traverse through map inside map in java

I am new to Java.
I have a map like this.
HashMap<String,HashMap<String,String>>mp;
How to traverse through this?
mp has another inside it.
I know the normal way of traversing through the map using entrySet;
You traverse the outer map using entrySet, then for each value of the outer map you traverse the inner map using entrySet.
for (Map.Entry<String,HashMap<String,String>> entry : mp.entrySet()) {
for (Map.Entry<String,String> innerEntry : entry.getValue().entrySet()) {
...
}
}
You can try this code:
package com.test;
import java.util.HashMap;
import java.util.Set;
public class TestMain {
public static void main(String[] args) {
HashMap<String,HashMap<String,String>>mp= new HashMap<String,HashMap<String,String>>();
HashMap<String, String> innerMap1= new HashMap<String, String>();
innerMap1.put("1", "firstValueOf_InnerMap1");
innerMap1.put("2", "SecondValueOf_InnerMap1");
HashMap<String, String> innerMap2= new HashMap<String, String>();
innerMap2.put("1", "firstValueOf_InnerMap2");
innerMap2.put("2", "SecondValueOf_InnerMap2");
mp.put("one", innerMap1);
mp.put("two", innerMap2);
for (HashMap<String,String> innerHashMap : mp.values()) {
for (String value : innerHashMap.values()) {
System.out.println(value);
}
}
}
}
You can try this code:
Set hmset = hm.entrySet();
for (HashMap<String,String> innerMap : hm.values()) {
for (String st1 : innerMap.values()) {
System.out.println(st1);
}
}

Merging Treemaps in a list

I have a List<Map<String, Object>> which contains the following maps.
Map:{clusterList=[71051], senseId=65786, totalCluster=1}
Map:{clusterList=[71051], senseId=65787, totalCluster=1}
Map:{clusterList=[4985, 71052], senseId=65788, totalCluster=2}
Map:{clusterList=[125840,153610,167812, 65787, 204091, 32586, 65786], senseId=71051, totalCluster=7}
Map:{clusterList=[11470, 65788], senseId=71052, totalCluster=2}
I have traversed the map and checked if senseId is present in the clusterList. But traversing each clusterList with senseId is taking long time with traditional for loop and also I am unable to get the merged list as the following
Map:{clusterList=[125840,153610,167812, 65787, 204091, 32586, 65786], senseId=71051, totalCluster=7}
Map:{clusterList=[4985,11470, 65788], senseId=71052, totalCluster=2}
I cant even remove the map with sensId present in the clusterList as it throws as concurrent operation exception.
Any ideas how to get to the result other than for loop as this list is very small so for loop still works. But I have list with 180 map entries and its hard to traverse the whole list and merge the maps.
I am stuck because the senseId of one map is present in clusterList of other map. So not able to merge them with simple search.
I'm rather sure that the problem is still underspecified. For example, it is not clear how to decide about the final senseId. When you have two maps
Map:{clusterList=[123,456,789], senseId=123, totalCluster=1}
Map:{clusterList=[123,456,666], senseId=456, totalCluster=1}
then (if I understood you correctly) they should be merged. But it is not clear whether the result should be a map
Map:{clusterList=[123,456,789,666], senseId=123, totalCluster=1}
or a map
Map:{clusterList=[123,456,789,666], senseId=456, totalCluster=1}
Apart from that, it seems like the "totalCluster" is the size of the cluster list. This means that it is most likely unnecessary, and if it is not unnecessary, you'd have to specify how it should be treated when two maps are merged.
However, here is a basic approach: One can create a map from senseId to maps with this senseId, and afterwards collect the maps that contain a certain senseId in their cluster list in order to find out which maps have to be merged.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class MapMergeTest
{
public static void main(String[] args)
{
List<Map<String, Object>> maps = createInput();
System.out.println("Input:");
for (Map<String, Object> map : maps)
{
System.out.println(map);
}
List<Map<String, Object>> result = createMergedMapsList(maps);
System.out.println("Result:");
for (Map<String, Object> map : result)
{
System.out.println(map);
}
}
private static List<Map<String, Object>> createInput()
{
List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>();
// senseId clusterList...
maps.add(createMap(65786, 71051));
maps.add(createMap(65787, 71051));
maps.add(createMap(65788, 4985, 71052));
maps.add(createMap(71051, 125840, 153610, 167812,
65787, 204091, 32586, 65786));
maps.add(createMap(71052, 11470, 65788));
return maps;
}
private static Map<String, Object> createMap(
Integer senseId, Integer ... clusters)
{
Map<String, Object> result = new LinkedHashMap<String, Object>();
result.put("senseId", senseId);
result.put("clusterList", new ArrayList<Integer>(Arrays.asList(clusters)));
return result;
}
private static List<Map<String, Object>> createMergedMapsList(
List<Map<String, Object>> maps)
{
Map<Integer, Map<String, Object>> senseIdToMap =
createSenseIdToMap(maps);
Map<Integer, Map<String, Object>> copy =
new LinkedHashMap<Integer, Map<String,Object>>(senseIdToMap);
for (Entry<Integer, Map<String, Object>> e : copy.entrySet())
{
Integer senseId = e.getKey();
Map<String, Object> map = e.getValue();
List<Integer> clusterList = getClusterList(map);
List<Map<String, Object>> mapsToMerge =
new ArrayList<Map<String,Object>>();
mapsToMerge.add(map);
for (Integer cluster : clusterList)
{
Map<String, Object> mapToMerge =
senseIdToMap.get(cluster);
if (mapToMerge != null)
{
mapsToMerge.add(mapToMerge);
senseIdToMap.remove(cluster);
}
}
if (mapsToMerge.size() > 1)
{
Map<String, Object> mergedMap = mergeMaps(mapsToMerge);
List<Integer> mergedClusterList = getClusterList(mergedMap);
mergedClusterList.remove(senseId);
senseIdToMap.put(senseId, mergedMap);
}
}
return new ArrayList<Map<String,Object>>(senseIdToMap.values());
}
private static Map<Integer, Map<String, Object>> createSenseIdToMap(
List<Map<String, Object>> maps)
{
Map<Integer, Map<String, Object>> senseIdToMap =
new LinkedHashMap<Integer, Map<String,Object>>();
for (Map<String, Object> map : maps)
{
Integer senseId = (Integer)map.get("senseId");
senseIdToMap.put(senseId, map);
}
return senseIdToMap;
}
private static Map<String, Object> mergeMaps(List<Map<String, Object>> list)
{
Map<String, Object> mergedMap = new LinkedHashMap<String, Object>();
Map<String, Object> firstMap = list.get(0);
mergedMap.put("senseId", firstMap.get("senseId"));
Set<Integer> mergedClusterList = new LinkedHashSet<Integer>();
for (Map<String, Object> map : list)
{
List<Integer> clusterList = getClusterList(map);
mergedClusterList.addAll(clusterList);
}
mergedMap.put("clusterList", new ArrayList<Integer>(mergedClusterList));
return mergedMap;
}
private static List<Integer> getClusterList(Map<String, Object> map)
{
Object object = map.get("clusterList");
return (List<Integer>)object;
}
}

Why does this Hashmap Iteration not work? I get a NullPointer Exception

Map<String, String> listOfIndexes = INDEXED_TABLES.get(tableName);
Iterator it = listOfIndexes.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
System.out.println(pairs.getKey());
}
My Hashmap is like this :
public static Map<String, Map<String, String>> INDEXED_TABLES = new HashMap<String, Map<String, String>>()
{{
put("employee", EMPLOYEE);
}};
public static Map<String, String> EMPLOYEE = new HashMap<String, String>()
{{
put("name", "Test");
put("age", "Test");
put("sex", "test");
}};
This is because you outsmarted yourself: your initializers depend on the order of execution. At the time this line runs
put("employee", EMPLOYEE);
EMPLOYEE is still null, so that's what gets put into your Map<String,Map<String,String>>.
You can switch the order of initializers to fix this problem. However, you would be better if you put initialization code into a separate initializer, rather than using anonymous classes with custom initializers:
public static Map<String, Map<String, String>> INDEXED_TABLES = new HashMap<String, Map<String, String>>();
public static Map<String, String> EMPLOYEE = new HashMap<String, String>();
static {
EMPLOYEE.put("name", "Test");
EMPLOYEE.put("age", "Test");
EMPLOYEE.put("sex", "test");
INDEXED_TABLES.put("employee", EMPLOYEE);
}
It looks like you are putting EMPLOYEE into the map before it has been initialized, so it will be null (and remain so, even if you assign something to EMPLOYEE later).
Reverse the order of the two statements.
Or, while in general I disapprove of the double-brace-initializer (hopefully, we'll get proper Collection literals in Java 8):
public static Map<String, Map<String, String>> INDEXED_TABLES =
new HashMap<String, Map<String, String>>(){{
put("employee", new HashMap<String, String>(){{
put("name", "Test");
put("age", "Test");
put("sex", "test");
}}
}}

Categories