Related
TreeMap<String, HashMap<String, String>> myData = new TreeMap<>();
HashMap<String, String> data = new HashMap<>(); //data present in this map will be name as key & Values will rest other details
HashMap<String, String> lock = new HashMap<>(); //data present in this map Will be id as Key & Values will be name+Email
Iterator itr = lock.entrySet().iterator();
Iterator trans = data.entrySet().iterator();
HashMap<String, String> vessel = new HashMap<>(); //Temp Holding of EachKey & value of name as key and rest as values
TreeMap demo=new TreeMap();
while (itr.hasNext()) {
Entry e = (Entry) itr.next();
String key = (String) e.getKey();
name = ReadExcel.getString((String) e.getValue(), 0);
String email = ReadExcel.getString((String) e.getValue(), 1);
while (trans.hasNext()) {
vessel.clear();
Entry ex = (Entry) trans.next();
String NameVs = (String) ex.getKey();
String emailVs = ReadExcel.getString((String) ex.getValue(), 0);
if (name.equalsIgnoreCase(NameVs) && email.equalsIgnoreCase(emailVs)) {
vessel.put(NameVs, data.get(NameVs));
//System.err.println(vessel.values());
myData.put(key, vessel); //Putting data in treeMap
System.out.println(myData.entrySet());
break;
}
}
trans = data.entrySet().iterator();
}
Need output as
[1={RAM=aa#gmail.com Domulur 7894561230 }, 2={ANIL=xyZ#gmail.com MUM 8464648848 }] . If i have some data as "ID Name Email Address Mob". But the problem is if i use clear() data is replaced by last row data .For, Ex: [1={ANIL=xyZ#gmail.com MUM 8464648848 }, 2={ANIL=xyZ#gmail.com MUM 8464648848 }] and if i don't use clear(), values are appending. For ex, [1={RAM=aa#gmail.com Domulur 7894561230,ANIL=xyZ#gmail.com MUM 8464648848 }, 2={RAM=aa#gmail.com Domulur 7894561230,ANIL=xyZ#gmail.com MUM 8464648848 }].
Need Help Thanks.
You use the same HashMap<String, String> instance as value for all the keys of your TreeMap, so of course all the keys will have the same value.
You should create a new HashMap for each key:
....
while (itr.hasNext()) {
Entry e = (Entry) itr.next();
String key = (String) e.getKey();
name = ReadExcel.getString((String) e.getValue(), 0);
String email = ReadExcel.getString((String) e.getValue(), 1);
while (trans.hasNext()) {
HashMap<String, String> vessel = new HashMap<>();
Entry ex = (Entry) trans.next();
String NameVs = (String) ex.getKey();
String emailVs = ReadExcel.getString((String) ex.getValue(), 0);
if (name.equalsIgnoreCase(NameVs) && email.equalsIgnoreCase(emailVs)) {
vessel.put(NameVs, data.get(NameVs));
myData.put(key, vessel); //Putting data in treeMap
break;
}
}
trans = data.entrySet().iterator();
}
....
I have a nested HashMap (outer_map), which has another HashMap inside of it as a value (inner_map), such implemented as
Map<String, HashMap<String, String>> outer_map = new HashMap<String, HashMap<String, String>>();
Map<String, String> inner_map = new HashMap<String, String>();
The figure below illustrates the whole structures of the maps:
To make the long story short, I need to compare and search values inside the outer_map's vlaue (inner_map) by String Array items, and then produce another String Array to add matched items.
If the String Array has there elements which are the same as one of the inner_map's random (for example; value2, value1, and value7) values, how can I search and compare these items to add to another String Array?
The latest code snippet I tried and I couldn't succeed:
if( !( theStringArray.equals("") ) )
{
while( outer_map.keySet().iterator().hasNext() )
{
for( int i=0; i <= theStringArray.length; i++)
{
// outer_map keys are order as 1,2,3,..,8
theStringArray[i] = outer_map.get(String.valueOf(i+1)).get("key1");
...
}
}
}
EDIT: Map generating function
private void parse(String in) throws IOException
{
reader = new JsonReader(new StringReader(in));
...
int nodeCounter = 1;
while(reader.hasNext())
{
...
String nameAsKey1 = "blabla"; // value1
inner_map.put("name", nameAsKey1);
String surnameAsKey2 = "blabla"; // value2
inner_map.put("surname", surnameAsKey2);
...
outer_map.put(String.valueOf(nodeCounter), (HashMap<String, String>) inner_map);
inner_map = new HashMap<String, String>();
nodeCounter++;
}
}
EDIT: I don't know how I can explain the issue more clearly, but may be this will help to understand about it: Map structure
I assume you have an array of String and a Map of map. Now you want to search the value fields of inner map against the array of String and if make a new string array with matching values.
If that is the case the below program will help you..
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class InnerMapSearch {
public static void main(String[] args) {
Map<String, HashMap<String, String>> outer_map = new HashMap<String, HashMap<String, String>>();
Map<String, String> inner_map = new HashMap<String, String>();
String[] searchParams = {"blabla1", "blabla3", "blabla20"};
//Populating the map
int reader = 1;
while (reader < 10) {
String nameAsKey1 = "blabla" + reader; // value1
inner_map.put("name", nameAsKey1);
String surnameAsKey2 = "blabla" + reader; // value2
inner_map.put("surname", surnameAsKey2);
outer_map.put(String.valueOf(reader), (HashMap<String, String>) inner_map);
inner_map = new HashMap<String, String>();
reader++;
}
//Searching
Set<String> searchResults = new HashSet<String>(); // Using set to avoid duplicate
// Iterate over the outer map
for(String key : outer_map.keySet()){
// Iterate through each inner_map value of outer map
for(Entry<String, String> innerEntry : outer_map.get(key).entrySet()){
// Iterate through the list of search params and see if its present in inner_hashmap
for(String searchParam : searchParams){
if(searchParam.equals(innerEntry.getValue())){
// The search parameter is in inner map so adding to result.
searchResults.add(searchParam);
}
}
}
}
// Converting the list to an array.
String[] searchResultsArray = searchResults.toArray(new String[searchResults.size()]);
}
}
Okay so I have spent several hours trying to wrap my head around this concept of a HashMap in Java but am just not able to figure it out. I have looked at many tutorials but none seem to address my exact requirement and I cannot get it to work.
I am trying to create an associative multi dimensional array in Java (or something similar) so that I can both save to and retrieve from the array with keys that are Strings.
This is how I would do it in PHP and explains it best what I am trying to do:
//loop one - assign the names
myArray['en']['name'] = "english name";
myArray['fr']['name'] = "french name";
myArray['es']['name'] = "spanish name";
//loop two - assign the description
myArray['en']['desc'] = "english description";
myArray['fr']['desc'] = "french description";
myArray['es']['desc'] = "spanish description";
//loop three - assign the keywords
myArray['en']['keys'] = "english keywords";
myArray['fr']['keys'] = "french keywords";
myArray['es']['keys'] = "spanish keywords";
//later on in the code be able to retrive any value similar to this
english_name = myArray['en']['name'];
french_name = myArray['fr']['name'];
spanish_name = myArray['es']['name'];
This is what I tried in Java but it is not working:
HashMap<String, HashMap<String, String>> myArray = new HashMap<String, HashMap<String, String>>();
myArray.put("en" , put("name", "english name")); //gives me "cannot find symbol" at second put
myArray.put("en" , ("name", "english name")); //gives me "')' expected" after second comma
So I am sure its something simple that I am missing but please point it out because this is very frustrating!
Thanks
EDIT:
So here is some working code on how I implemented the answer I accepted:
import java.util.*;
HashMap<String, HashMap<String, String>> finalArray = new HashMap<String, HashMap<String, String>>();
String[] langArray = {"en","fr","de","no","es"};
//Initialize each language key ahead of time
for(String lang : langArray) { // foreach lang in langArray
if (!finalArray.containsKey(lang)) {
finalArray.put(lang, new HashMap<String, String>());
}
}
//loop one - assign names
for(String lang : langArray) {
String theName = lang + " name"; //go get the name from somewhere
finalArray.get(lang).put("name", theName);
}
//loop two - assign description
for(String lang : langArray) {
String theDesc = lang + " description"; //go get the description from somewhere
finalArray.get(lang).put("desc", theDesc);
}
//loop three - assign keywords
for(String lang : langArray) {
String theKeys = lang + " keywords"; //go get the keywords from somewhere
finalArray.get(lang).put("keys", theKeys);
}
//display output
for(String lang : langArray) {
System.out.println("LANGUAGE: " + lang);
System.out.println(finalArray.get(lang).get("name"));
System.out.println(finalArray.get(lang).get("desc"));
System.out.println(finalArray.get(lang).get("keys"));
}
//example to retrieve/get values
String english_name = finalArray.get("en").get("name");
String french_desc = finalArray.get("fr").get("desc");
HashMap<String, HashMap<String, String>> myArray = new HashMap<String, HashMap<String, String>>();
if (!myArray.containsKey("en")) {
myArray.put("en", new HashMap<String, String>());
}
myArray.get("en").put("name", "english name");
In Java you have to be explicit about when you are creating an object. In this case first we check if there is already a HashMap object stored in our outer HashMap under the key "en". If not, we create an empty one.
Now to put a new value into it we have to first get it from the outer HashMap, then put the new value.
HashMap<String, HashMap<String, String>> myArray = new HashMap<String, HashMap<String, String>>();
HashMap<String, String> value = new HashMap<String, String>();
value.put("name", "English name");
value.put("desc", "English description");
value.put("keys", "English keywords");
myArray.put("en" , value);
value = new HashMap<String, String>();
value.put("name", "French name");
value.put("desc", "French description");
value.put("keys", "French keywords");
myArray.put("fr" , value);
Unfortunately, there's no concise syntax for constructing populated maps in Java. You'll have to write it out long-hand. A separate helper method can make it a little simpler:
HashMap<String, String> makeMap(String name, String desc, String keys) {
HashMap<String, String> map = new HashMap<>();
// Before Java 7, above must be: new HashMap<String, String>();
map.put("name", name);
map.put("desc", desc);
map.put("keys", keys);
}
Then:
HashMap<String, HashMap<String, String>> myArray = new HashMap<>();
myArray.put("en",
makeMap("english name", "english description", "english keywords"));
// etc.
You would retrieve it with:
english_name = myArray.get("en").get("name");
import java.util.HashMap;
public class Main
{
public static void main(String[] args) {
// Creating array
HashMap<String, HashMap<String, String>> myArray = new HashMap<String, HashMap<String, String>>();
// Setting values
for(int i=0; i<100;i++) {
myArray.put("key1"+i, new HashMap<String, String>());
myArray.get("key1"+i).put("key2"+i, "value"+i);
}
// Getting values
for(int i=0; i<100; i++) {
System.out.println(myArray.get("key1"+i).get("key2"+i));
}
}
}
I really liked the example by "dAv dEv", though he didn't really fill his double array of keys (I added a loop within a loop). I also like TreeMaps better than HashMaps because they aren't as random.
import java.util.Map;
import java.util.TreeMap;
TreeMap<String, TreeMap<String, String>> myArray =
new TreeMap<String, TreeMap<String, String>>();
String[] roles = { "Help Desk", "Administrator", "Super Use", ... };
String[] elements = { "Hydrogen", "Helium", "Lithium", "Beryllium", ... };
// Setting values TODO: read data values from Excel spreadsheet (or wherever)
for(String role : roles) {
myArray.put(role, new TreeMap<String, String>());
for (String elementName : elements) {
String value = Utils.getHumanName("first", true);
myArray.get(role).put(elementName, value);
}
}
// Getting values
for (Map.Entry<String,TreeMap<String,String>> entry1 : myArray.entrySet()) {
String key1 = entry1.getKey();
TreeMap<String,String> value1 = entry1.getValue();
for (Map.Entry<String,String> entry2 : value1.entrySet()) {
String key2 = entry2.getKey();
String value2 = entry2.getValue();
System.out.println("(" + key1 + ", " + key2 + ") = " +
myArray.get(key1).get(key2));
}
}
P.S. I used Utils.getHumanName() as my data generator. You will need to use your own.
String format is (not json format):
a="0PN5J17HBGZHT7JJ3X82", b="frJIUN8DYpKDtOLCwo/yzg="
I want convert this string to a HashMap:
key a with value 0PN5J17HBGZHT7JJ3X82
key b with value frJIUN8DYpKDtOLCwo/yzg=
Is there a convenient way? Thanks
What I've tried:
Map<String, String> map = new HashMap<String, String>();
String s = "a=\"00PN5J17HBGZHT7JJ3X82\",b=\"frJIUN8DYpKDtOLCwo/yzg=\"";
String []tmp = StringUtils.split(s,',');
for (String v : tmp) {
String[] t = StringUtils.split(v,'=');
map.put(t[0], t[1]);
}
I get this result:
key a with value "0PN5J17HBGZHT7JJ3X82"
key b with value "frJIUN8DYpKDtOLCwo/yzg
for key a, the start and end double quotation marks(") is unwanted; for key b, the start double quotation marks(") is unwanted and the last equals sign(=) is missing.
Sorry for my poor english.
Probably you don't care that it's a HashMap, just a Map, so this will do it, since Properties implements Map:
import java.io.StringReader;
import java.util.*;
public class Strings {
public static void main(String[] args) throws Exception {
String input = "a=\"0PN5J17HBGZHT7JJ3X82\", b=\"frJIUN8DYpKDtOLCwo/yzg=\"";
String propertiesFormat = input.replaceAll(",", "\n");
Properties properties = new Properties();
properties.load(new StringReader(propertiesFormat));
System.out.println(properties);
}
}
Output:
{b="frJIUN8DYpKDtOLCwo/yzg=", a="0PN5J17HBGZHT7JJ3X82"}
If you absolutely need a HashMap, you can construct one with the Properties object as input: new HashMap(properties).
Added few changes in Ryan's code
public static void main(String[] args) throws Exception {
String input = "a=\"0PN5J17HBGZHT7JJ3X82\", b=\"frJIUN8DYpKDtOLCwo/yzg=\"";
input=input.replaceAll("\"", "");
String propertiesFormat = input.replaceAll(",", "\n");
Properties properties = new Properties();
properties.load(new StringReader(propertiesFormat));
Set<Entry<Object, Object>> entrySet = properties.entrySet();
HashMap<String,String > map = new HashMap<String, String>();
for (Iterator<Entry<Object, Object>> it = entrySet.iterator(); it.hasNext();) {
Entry<Object,Object> entry = it.next();
map.put((String)entry.getKey(), (String)entry.getValue());
}
System.out.println(map);
}
Split the String on the Basis of commas (",") and then with with ("=")
String s = "Comma Separated String";
HashMap<String, String> map = new HashMap<String, String>();
String[] arr = s.split(",");
String[] arStr = arr.split("=");
map.put(arr[0], arr[1]);
You can also use the regex as below.
Map<String,String> data = new HashMap<String,String>();
Pattern p = Pattern.compile("[\\{\\}\\=\\, ]++");
String[] split = p.split(text);
for ( int i=0; i+2 <= split.length; i+=2 ){
data.put( split[i], split[i+1] );
}
return data;
have a string like A=B&C=D&E=F, how to parse it into map?
I would use split
String text = "A=B&C=D&E=F";
Map<String, String> map = new LinkedHashMap<String, String>();
for(String keyValue : text.split(" *& *")) {
String[] pairs = keyValue.split(" *= *", 2);
map.put(pairs[0], pairs.length == 1 ? "" : pairs[1]);
}
EDIT allows for padded spaces and a value with an = or no value. e.g.
A = minus- & C=equals= & E==F
just use guava Splitter
String src="A=B&C=D&E=F";
Map map= Splitter.on('&').withKeyValueSeparator('=').split(src);
public class TestMapParser {
#Test
public void testParsing() {
Map<String, String> map = parseMap("A=B&C=D&E=F");
Assert.assertTrue("contains key", map.containsKey("A"));
Assert.assertEquals("contains value", "B", map.get("A"));
Assert.assertTrue("contains key", map.containsKey("C"));
Assert.assertEquals("contains value", "D", map.get("C"));
Assert.assertTrue("contains key", map.containsKey("E"));
Assert.assertEquals("contains value", "F", map.get("E"));
}
private Map<String, String> parseMap(final String input) {
final Map<String, String> map = new HashMap<String, String>();
for (String pair : input.split("&")) {
String[] kv = pair.split("=");
map.put(kv[0], kv[1]);
}
return map;
}
}
String t = A=B&C=D&E=F;
Map map = new HashMap();
String[] pairs = t.split("&");
//TODO 1) Learn generis 2) Use gnerics
for (String pair : pairs)
{
String[] kv = pair.split("=");
map.put(kv[0], kv[1]);
}
Split the string (either using a StringTokenizer or String.split()) on '&'. On each token just split again on '='. Use the first part as the key and the second part as the value.
It can also be done using a regex, but the problem is really simple enough for StringTokenizer.