Putting JSON values into Hashmap - java

I have JSON value like below,
{ "emp_id": 1017,
"emp_name": "karthik Y",
"emp_designation": "Manager",
"department": "JavaJson",
"salary": 30000,
"direct_reports":
[
"Nataraj G",
"Kalyan",
"Mahitha"
]
}
HashMap < String, String[] >input1 = new HashMap < String, String[] >();
input1.put("empid","1017");
input1.put("emp_name","karthik");
input1.put("emp_designation","manager");
input1.put("salary","30000");
now I want to add next array that is direct_report to put as next key and value(entire array shoud be come one key and value). Someone please help out.

Hashmap is a key/value storage, where keys are unique. You can convert your JSON to string and then store it as a value to the hashmap. For example something like below:
public static void main(String[] args) {
String json = "{ \"emp_id\": 1017,"
+ "\"emp_name\": \"karthik Y\","
+ "\"emp_designation\": \"Manager\","
+ "\"department\": \"JavaJson\","
+ "\"salary\": 30000,"
+ "\"direct_reports\": ["
+ "\"Nataraj G\","
+ "\"Kalyan\","
+ "\"Mahitha\"]}";
HashMap<String, String> jsonStore = new HashMap<String, String>();
jsonStore.put("myJson", json);
System.out.println(jsonStore.get("myJson"));
}
You need can also use the 'org.json' library to
Create JSON object manually
Convert existing JSONObject to String representation
Convert JSON string to JSONObject
You can also have the following solution:
JSONObject jsonObject = new JSONObject();
jsonObject.put("empt_id", 1017);
jsonObject.put("emp_name", "karthik");
HashMap<String, JSONObject> jsonObjectStore = new HashMap<String, JSONObject>();
jsonObjectStore.put("myJsonObject", jsonObject);
HashMap<JSONObject, String> jsonObjectStore2 = new HashMap<JSONObject, String>();
jsonObjectStore2.put(jsonObject, "myJson");
Make sure that you download the org.json jar file and put it in your classpath to be able to use the JSONObject. You can download the jar from here.
In order to put each of those values into map as single key/value entry. You have mentioned it yourself, it should work without any problem. See below methods:
Method 1
Everything in Java is Object, String inherits Object, String[] inherits object. You can have the following solution:
HashMap<String, Object> myObjectStore4 = new HashMap<String, Object>();
String[] directReports4 = new String[]{"Natraj G", "Kalyan", "Mahitha"};
myObjectStore4.put("emp_id", new String("123"));
myObjectStore4.put("emp_name", new String("Raf"));
// others ....
myObjectStore4.put("directReports", directReports4);
Method 2
To store the fields as key/value and if you can afford converting the array to String (which represents all array elements comma separated then use this method).
HashMap<String, String> myObjectStoreTwo = new HashMap<String, String>();
String[] directReports2 = new String[]{"Natraj G", "Kalyan", "Mahitha"};
myObjectStoreTwo.put("emp_id", "123");
myObjectStoreTwo.put("emp_name", "Raf");
myObjectStoreTwo.put("salary", "222");
//Converts array to comma separated String
myObjectStoreTwo.put("directReports",Arrays.toString(directReports2));
Method 3
In the expense of having Hash Map to store String key and Array value. You have to put other elements as array too.
HashMap<String, String[]> myObjectStore3 = new HashMap<String, String[]>();
String[] directReports3 = new String[]{"Natraj G", "Kalyan", "Mahitha"};
myObjectStore3.put("emp_id", new String[]{123 + ""});
myObjectStore3.put("salary", new String[]{32312 + ""});
myObjectStore3.put("directReports", directReports3);

Use a jackson ObjectMapper. Try if this works
String json = "{....}"
HashMap<String,Object> mappedVals = new ObjectMapper().readValue(
json ,
new TypeReference<HashMap<String,Object>>() {
});

Related

Connect two HashMap Values

I've got this JSON string:
String json = "{\"countries\":{\"2\":\"China\",\"3\":\"Russia \",\"4\":\"USA\"},\"capitals\":{\"2\":Beijing,\"4\":null,\"3\":Moscow}}";
I converted string to HashMap, using this:
HashMap<String,Object> map = new Gson().fromJson(json, new TypeToken<HashMap<String, Object>>(){}.getType());
System.out.println(map.get("countries")+"#####"+map.get("capitals"));
And now my output is:
{2=China, 3=Russia , 4=USA}#####{2=Beijing, 4=null, 3=Moscow}
I would like to connect this values by numbers. I want to create two ArrayList like this:
A)- [China,Russia,USA]
B)- [Beijing,Moscow,null]
How can i do it?
First, you need to cast map.get("label") to LinkedTreeMap<Integer, String>, then create new ArrayList with it's values
String json = "{\"countries\":{\"2\":\"China\",\"3\":\"Russia \",\"4\":\"USA\"},\"capitals\":{\"2\":Beijing,\"4\":null,\"3\":Moscow}}";
HashMap<String,TreeMap<Integer, String>> map = new Gson().fromJson(json, new TypeToken<HashMap<String, TreeMap<Integer, String>>>(){}.getType());
ArrayList<String> countries = new ArrayList<>(map.get("countries").values());
System.out.println(countries);
ArrayList<String> capitals = new ArrayList<>(map.get("capitals").values());
System.out.println(capitals);
You can iterate over the country keyset to fill the capital array:
List<String> countries = new ArrayList<>(countriesMap.values());
List<String> capitals = new ArrayList<>();
for (String countryKey : countriesMap.keySet()) {
capitals.add(capitalsMap.get(countryKey));
}

String to map conversion java

Code:
Map test = new HashMap<String,String>();
test.put("1", "erica");
test.put("2", "frog");
System.out.println(test.toString());
This code gives output as :
{1=erica, 2=frog}
I want this output to be again put in a map as key value-pair .
Any suggestions how can i implement this ?
Or is ther any predefined utility class for conversion of the output to HashMap again ?
For me a proper way would be to use a JSON parser like Jackson since the way a HashMap is serialized is not meant to be parsed after such that if you use specific characters like = or , they won't be escaped which makes it unparsable.
How to serialize a Map with Jackson?
ObjectMapper mapper = new ObjectMapper();
String result = mapper.writeValueAsString(myMap);
How to deserialize a String to get a Map with Jackson?
ObjectMapper mapper = new ObjectMapper();
Map map = mapper.readValue(contentToParse, Map.class);
You can try to use this:
String[] tk = mystring.split(" |=");
Map<String, String> map = new HashMap<>();
for (int i=0; i < tk.length-1; i++)
{
map.put(tk[i], tk[i]);
}
return map;
If you want to replicate the Java code filling the map, you may use something like this:
StringBuilder sb = new StringBuilder("Map<String, String> test = new HashMap<>();");
for(Map.Entry<?, ?> entry : test.entrySet())
{
sb.append("\ntest.put(\"");
sb.append(entry.getKey());
sb.append("\", \"");
sb.append(entry.getValue());
sb.append("\");");
}
String string = sb.toString();
System.out.println(string);
But I agree with the comments, that in many applications a format such as JSON is more appropriate to serialize a map.
Note that the above solution does not escape strings, it only works if the strings don't contain characters like " or \n. If you need to handle these cases it will become more complicated.
You could try the following:
String out = test.toString();
Map<String, String> newMap = new HashMap();
// remove the first and last "{", "}"
out = out.subString(1,out.size()-1)
String[] newOut = out.split(", ");
for (int i=0; i<newOut.length;i++){
// keyValue is size of 2. cell 0 is key, cell 1 is value
String[] keyValue = newOut.split("=");
newMap.put(keyValue[0], keyValue[1]);
}
I haven't tested the code in java i just wrote from my mind. I hope it will work

represent JSON file in a java program for querying values by key

I want to represent this file in my java program.
What I want to do is quickly search through it by "key" value, so for instance, given the value P26 I'd want to return spouse.
Maybe I can read it in as a HashMap using gson as I did with this program.
But what to do about this wonky structure:
{
"properties": {
"P6": "head of government",
"P7": "brother",
...
How could I fit that well into a HashMap? Is HashMap even the best choice?
I've sort of simplified it to this:
{
"P6": "head of government",
"P7": "brother",
"P9": "sister",
"P10": "video",
"P14": "highway marker",
"P15": "road map",
"P16": "highway system",
"P17": "country",
"P18": "image",
I've tried to use this code, but it outputs null
/*
* P values file
*/
String jsonTxt_P = null;
File P_Value_file = new File("properties-es.json");
//read in the P values
if (P_Value_file.exists())
{
InputStream is = new FileInputStream("properties-es.json");
jsonTxt_P = IOUtils.toString(is);
}
Gson gson = new Gson();
Type stringStringMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String,String> map = gson.fromJson(jsonTxt_P, stringStringMap);
System.out.println(map);
It doesn't work because that file is not a Map<String, String>. it has a properties element, which contains a mapping, and a missing element, which contains an array. This mismatch will cause Json to return null, which is what you're seeing. Instead, try doing this:
public class MyData {
Map<String, String> properties;
List<String> missing;
}
And then, to deserialize, do:
MyData data = gson.fromJson(jsonTxt_P, MyData.class);
Map<String, String> stringStringMap = data.properties;
This will make the data structure match the structure of the json, and allow json to properly deserialize.

Convert JSON object with duplicate keys to JSON array

I have a JSON string that I get from a database which contains repeated keys. I want to remove the repeated keys by combining their values into an array.
For example
Input
{
"a":"b",
"c":"d",
"c":"e",
"f":"g"
}
Output
{
"a":"b",
"c":["d","e"],
"f":"g"
}
The actual data is a large file that may be nested. I will not know ahead of time what or how many pairs there are.
I need to use Java for this. org.json throws an exception because of the repeated keys, gson can parse the string but each repeated key overwrites the last one. I need to keep all the data.
If possible, I'd like to do this without editing any library code
As of today the org.json library version 20170516 provides accumulate() method that stores the duplicate key entries into JSONArray
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("a", "b");
jsonObject.accumulate("c", "d");
jsonObject.accumulate("c", "e");
jsonObject.accumulate("f", "g");
System.out.println(jsonObject);
Output:
{
"a":"b",
"c":["d","e"],
"f":"g"
}
I want to remove the repeated keys by combining their values into an array.
Think other than JSON parsing library. It's very simple Java Program using String.split() method that convert Json String into Map<String, List<String>> without using any library.
Sample code:
String jsonString = ...
// remove enclosing braces and double quotes
jsonString = jsonString.substring(2, jsonString.length() - 2);
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String values : jsonString.split("\",\"")) {
String[] keyValue = values.split("\":\"");
String key = keyValue[0];
String value = keyValue[1];
if (!map.containsKey(key)) {
map.put(key, new ArrayList<String>());
}
map.get(key).add(value);
}
output:
{
"f": ["g"],
"c": ["d","e"],
"a": ["b"]
}
In order to accomplish what you want, you need to create some sort of custom class since JSON cannot technically have 2 values at one key. Below is an example:
public class SomeClass {
Map<String, List<Object>> values = new HashMap<String, List<Object>>();
public void add(String key, Object o) {
List<Object> value = new ArrayList<Object>();
if (values.containsKey(key)) {
value = values.get(key);
}
value.add(o);
values.put(key, value);
}
public JSONObject toJson() throws JSONException {
JSONObject json = new JSONObject();
JSONArray tempArray = null;
for (Entry<String, List<Object>> en : values.entrySet()) {
tempArray = new JSONArray();
for (Object o : en.getValue()) {
tempArray.add(o);
}
json.put(en.getKey(), tempArray);
}
return json;
}
}
You can then retrieve the values from the database, call the .add(String key, Object o) function with the column name from the database, and the value (as the Object param). Then call .toJson() when you are finished.
Thanks to Mike Elofson and Braj for helping me in the right direction. I only wanted to have the keys with multiple values become arrays so I had to modify the code a bit. Eventually I want it to work for nested JSON as well, as it currently assumes it is flat. However, the following code works for what I need it for at the moment.
public static String repeatedKeysToArrays(String jsonIn) throws JSONException
{
//This assumes that the json is flat
String jsonString = jsonIn.substring(2, jsonIn.length() - 2);
JSONObject obj = new JSONObject();
for (String values : jsonString.split("\",\"")) {
String[] keyValue = values.split("\":\"");
String key = keyValue[0];
String value = "";
if (keyValue.length>1) value = keyValue[1];
if (!obj.has(key)) {
obj.put(key, value);
} else {
Object Oold = obj.get(key);
ArrayList<String> newlist = new ArrayList<String>();
//Try to cast as JSONArray. Otherwise, assume it is a String
if (Oold.getClass().equals(JSONArray.class)) {
JSONArray old = (JSONArray)Oold;
//Build replacement value
for (int i=0; i<old.length(); i++) {
newlist.add( old.getString(i) );
}
}
else if (Oold.getClass().equals(String.class)) newlist = new ArrayList<String>(Arrays.asList(new String[] {(String)Oold}));
newlist.add(value);
JSONArray newarr = new JSONArray( newlist );
obj.put(key,newarr);
}
}
return obj.toString();
}

Java HashMap associative multi dimensional array can not create or add elements

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.

Categories