When I create this objects, i do like this:
random_fields= new ArrayList<HashMap<String, String>>();
try {
// Getting Array of fields
JSONArray fields= json.getJSONArray("fields");
// Looping through All fields
for(int i = 0; i < fields.length(); i++) {
JSONObject jobj = fields.getJSONObject(i);
// Creating new HashMap
HashMap<String, String> map_aux = new HashMap<String, String>();
// Adding each child node to HashMap key => value
map_aux.put("field_id", jobj.getString("field_id"));
map_aux.put("field_text", jobj.getString("field_text"));
}
// Adding HashList to ArrayList
random_fields.add(map_aux);
}
And then when I try to access to every single field in the Arraylist of Hashmaps... i do like this:
For example:
editText1.setText(random_fields.get(0).get("field_text"));
and it gives me a Java Null Pointer Error... but if I do:
System.out.println(random_challenges.get(0).get("field_text"));
It works and it prints in my debug console.. the field text correctly.. Which can be the solution?
The code where you set your editText looks right. The only difference I can spot here is that you use random_challenges in your System.out.println method and random_fields in your setText method.
Would you like to provide some actual code files (not just the snippets) and I can look closer, but from what you have provided I would venture to guess that what is happening is that the values you think you are populating your hash map with (in the for loop) go out of scope and are cleaned up leaving you with the NULL reference.
You console, since it persists, keeps the data instantiated long enough for you to debug print it.
Related
I am using the following libraries to create some JSON object.
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
The json I am trying to create is this:
{
"function": "create_contact_group",
"parameters": [{
"user_id": "teer",
"comp_id": "97",
"contact_group_name": "Test01",
"invite_user_list": [{
"invite_user_id": "steve"
}]
}]
}
My function looks like this:
public JSONObject createJSONRequest() {
/* Create json object */
JSONObject jsonObject = new JSONObject();
Map<String, String> map = new HashMap<>();
map.put("user_id", "teer");
map.put("comp_id", "97");
map.put("contact_group_name", "Test01");
List<String> mInviteUserList = new ArrayList<>();
mInviteUserList.add("steve");
/* Create the list of invitee */
Map<String, String> inviteList = new HashMap<>();
for(String user : mInviteUserList) {
inviteList.put("invite_user_id", user);
}
/* Add the invitees into the json array */
JSONArray inviteArray = new JSONArray();
inviteArray.add(inviteList);
/* Add the json array to the json object */
jsonObject.put("invite_user_list", inviteArray);
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);
jsonObject.put("parameters", parameterlist);
jsonObject.put("function", "create_contact_group");
Log.d(TAG, "jsonObject: " + jsonObject.toJSONString());
return jsonObject;
}
However, the function crashes when I get to the following line:
Log.d(TAG, "jsonObject: " + jsonObject.toJSONString())
I think it has something to do with this line here:
parameterlist.add(jsonObject);
Stacktrace:
java.lang.StackOverflowError java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95) at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:132)
at java.lang.StringBuffer.append(StringBuffer.java:126) at org.json.simple.JSONValue.escape(JSONValue.java:266) at org.json.simple.JSONObject.toJSONString(JSONObject.java:116)
Many thanks for any suggestions,
There are a couple of issues in your code.
One issue is that the structure you create in the java code will not match the structure that you show above. This I will try to describe a bit below.
The second issue is that you get a stackoverflow exception (which you know but don't know why).
The stackoverflow exception is thrown cause the program runs out of the stack memory assigned by the computer. Why you ask? Well, cause you create a recursive or cyclic JSON object.
This isn't good, but its not that big a deal cause its kinda easy to fix.
So why does the program throw this exception? Well, look at the following snippet:
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);
jsonObject.put("parameters", parameterlist);
jsonObject.put("function", "create_contact_group");
You create a JSONArray and then add the JSONObject created before to the array.
After that you add the same array to the object that is already in the array.
I expect that you see the issue with that!
So, that should not be done.
And how to fix this? Well, I kinda think its better that I describe how you should write the code to get the structure you are actually asking for, so I'll try do that...
What to do...?
A JSON (JavaScript Object Notation) -object is always declared with this type of brackets: {} a JSON array with [], so, the JSON you are trying to generate should be in the following data types:
{ // <= Root object (a JSON-object).
"function": "create_contact_group", // <= Key in the root-object (where the key is a string and the value a string)
"parameters": [ // <= Key in the root-object (where the key is a string and the value is an array.
{ // <= Object inside the array.
"user_id": "teer", // Key (string/string)
"comp_id": "97", // Key (string/string)
"contact_group_name": "Test01", // Key (string/string)
"invite_user_list": [ // Key (string/array)
{ // Object inside the invite_user_list array
"invite_user_id": "steve" // Key (string/string)
}
]
}
]
}
So when creating the JSON-object in java, you will want to create a root object then add all the diff params inside it.
Adding a value to a JSONObject is done with the JSONObject.put(string, Object) method, where the string is a key and the object a value.
So to start, I would recommend creating the parameters list.
In your case, you use a HashMap for the objects, which is not really wrong, but not really necessary either, I would just stick to a JSONObject, which is not all that different than a HashMap<string, Object>.
So instead of map.put(...), you could do something like:
JSONObject param = new JSONObject();
param.put("user_id", "teer");
param.put("comp_id", "97");
param.put("contact_group_name", "Test01");
Now, one of the objects values should be an array (invite_user_id) and the easiest way to add an array to the object is to create a JSONArray and then just add it.
JSONArray inviteList = new JSONArray();
// Then you need to add an object to the array for each `user` that has invited.
// For-loop here maybe?
JSONObject invitee = new JSONObject();
invitee.put("invite_user_id", user);
inviteList,add(invitee); // This will make it into an array with objects, I.E., [ { "invite_user_id": "Steve" } ]
After creating the invite list, add it to the param object like:
param.put("invite_user_list", inviteList);
// Now, param should be in its own list too, so you should probably create a JSONArray for the params.
// Ill leave that to you, and we pretend we have a list of the param objects named "params".
And then at the end, you create the root object and set its values:
JSONObject root = new JSONObject();
root.put("parameters", params);
root.put("function", "create_contact_group");
And that should be it.
This should create a JSON-string with the structure that you made above. But I would recommend testing (and writing unit tests!) for this (especially as I have written this code in the browser!).
But why?!
I guess I should try to describe why your code was not working as the one I described above.
You start by creating a root object, so far so good (can create it at start or at the time you need it, doesn't really matter), after that you create a HashMap and add the properties to it.
So far this is also legit (you could later create a JSONObject from the map).
In the next part, you create an ArrayList (im not really sure why) and add a name to it, and then another HashMap which you add the single name to (key invite_user_list) inside a for-loop.
This is either not necessary (cause its just one name) or wrong (if there is supposed to be more names in a real life execution of the code), in case of unnecessary, the for-loop shouldn't be there and in case of "not like real life" it should not be added to a Map!
Instead the invieList should have been an array, and each entry added should have been a object which had the "invite_user_id" key set to the name.
After that, you add the inviteList HashMap to a newly created JSONArray, I guess this could be kinda okay, if you only want one object ever in the array, else I would recommend creating it before the loop and add each entry into it!
The inviteArray is then put inside the root object with the key invite_user_list, after that you create another JSONArray and add both the map (your parameters created at the start) and the JSONObject (root) created first of all.
But the thing you do after that, is why you are getting a stackoverflow exception, you add the parameterlist (which contains the jsonObject (root)) to the jsonObject, which makes the jsonObject exist inside an array that is inside itself!
This creates a cyclic JSON structure which will never end if the whole thing was to be unrolled, hence the computer throws the exception.
The structure of the resulting object would also be wrong, cause it would look something like this:
{ // Root (jsonObject)
"invite_user_list": [
{ "invite_user_id": "steve" }
]
"parameters": [
{ // The "map" hashmap
"user_id", "teer",
"comp_id": "97",
"contact_group_name": "Test01"
},
{ // The jsonObject object (which is also the root!)
"invite_user_list": [
{ "invite_user_id": "steve" }
],
"parameters": [
{ // The "map" hashmap
"user_id", "teer",
"comp_id": "97",
"contact_group_name": "Test01"
},
{
// The jsonObject object again (which is also the root and the parent!)
// ... and so on til eternity!
}
],
"function": "create_contact_group"
}
],
"function": "create_contact_group"
}
Extra...
I would like to add here at the end (where I hope you end up after reading the whole wall of text that I wrote above, cause you might have learnt something!) that there is a easier way of doing it.
Now, I haven't used this lib myself, but from what I understand, it should be able to serialize a whole object, the lib can be found at Googles github repos which can be used as a json serializer and convert a class-instance to a json string, then you could just create a class for the whole object and fill it up and serialize it at the end of the function, without using either JSONArray nor JSONObject.
The issue is due to recursion process that occurs when you are trying to add the JsonObject to JsonArray and viceVersa.
The thing you are doing is,
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);
And then
jsonObject.put("parameters", parameterlist);
The problem is when you print the object using jsonObject.toJSONString(), Then at first it will fetch the parameterlist then as jsonObject is part of the keyvalue pair on the parameterlist JsonArray it will refetch the jsonObject which then again fetch the parameterlist and this process continues on and hence causing the StackOverflow Issue.
The Quick Solution is to create new JsonObject while assigning the parameterList,
JSONArray parameterlist = new JSONArray();
parameterlist.add(map);
parameterlist.add(jsonObject);
JSONObject newJson = new JSONObject();
newJson.put("parameters", parameterlist);
System.out.println(newJson.toJSONString());
I have a json object like
{"0":"Andrew Smith"}
how can i get the value means Andrew Smith. I tried a lot but not getting.They key name will get change. I tried in this way
JsonObject jObject = new JsonObject(currentObj);
System.out.println(currentObj.toString());
Iterator i = jObject.keys();
String value = "";
while(i.hasNext()) {
String currentKey = String.valueOf(i.next());
Object currentValue = jObject.get(currentKey);
}
its not going into the loop. So how can i get the value at 0th position.
please help me. Thanks
Try to use Gson:
Map<Integer, String> map = new Gson().fromJson("{\"0\":\"Andrew Smith\"}", new TypeToken<Map<Integer, String>>(){}.getType());
System.out.println(map.entrySet().iterator().next().getValue());
Prints 'Andrew Smith'.
Get the iterator for keys and call getString for the first value
JSONObject obj = new JSONObject("{\"0\":\"Andrew Smith\"}");
Iterator<String> x = obj.keys();
if(x.hasNext())
Log.e("FACEBOOK", obj.getString(x.next()));
Your code works if you just fix all compiler errors.
i.e
It's JSONObject, not JsonObject.
currentObjis not in scope. I suppose you cut it out from somewhere where it is
but replacing it with at string literal will make it easier for other people to
test as well as eliminating one possible source of errors.
Fixing those, putting it in a method and declaring the exception made it work just
fine. Assuming whatever code you started with actually does compile I suggest checking
that the JSONObject in question really is what you think it is.
I created a HashMap to store a text file with the columns of information. I compared the key to a specific name and stored the values of the HashMap into an ArrayList. When I try to println my ArrayList, it only outputs the last value and leaves out all the other values that match that key.
This isn't my entire code just my two loops that read in the text file, stores into the HashMap and then into the ArrayList. I know it has something to do with my loops.
Did some editing and got it to output, but all my values are displayed multiple times.
My output looks like this.
North America:
[ Anguilla, Anguilla, Antigua and Barbuda, Antigua and Barbuda, Antigua and Barbuda, Aruba, Aruba, Aruba,
HashMap<String, String> both = new HashMap<String, String>();
ArrayList<String> sort = new ArrayList<String>();
//ArrayList<String> sort2 = new ArrayList<String>();
// We need a try catch block so we can handle any potential IO errors
try {
try {
inputStream = new BufferedReader(new FileReader(filePath));
String lineContent = null;
// Loop will iterate over each line within the file.
// It will stop when no new lines are found.
while ((lineContent = inputStream.readLine()) != null) {
String column[]= lineContent.split(",");
both.put(column[0], column[1]);
Set set = both.entrySet();
//Get an iterator
Iterator i = set.iterator();
// Display elements
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
if(me.getKey().equals("North America"))
{
String value= (String) me.getValue();
sort.add(value);
}
}
}
System.out.println("North America:");
System.out.println(sort);
System.out.println("\n");
}
Map keys need to be unique. Your code is working according to spec.
if you need to have many values for a key, you may use
Map<key,List<T>>
here T is String (not only list you can use any collection)
Some things seems wrong with your code :
you are iterating on the Map EntrySet to get just one value (you could just use the following code :
if (both.containsKey("North America"))
sort.add(both.get("North America"));
it seems that you can have "North America" more than one time in your input file, but you are storing it in a Map, so each time you store a new value for "North America" in your Map, it will overwrite the current value
I don't know what the type of sort is, but what is printed by System.out.print(sort); is dependent of the toString() implementation of this type, and the fact that you use print() instead of println() may also create problems depending on how you run your program (some shells may not print the last value for instance).
If you want more help, you may want to provide us with the following things :
sample of the input file
declaration of sort
sample of output
what you want to obtain.
I am not sure if it possible or not but I think it can be done using JSONArray.put method.
Heres my problem:
I have got two lists:
ArrayList<Students> nativeStudents;
ArrayList<transferStudents> transferStudents = nativeStudents.getTransferStudentsList();
The JSON that I generate with transferStudents list is right here: http://jsfiddle.net/QLh77/2/ using the following code:
public static JSONObject getMyJSONObject( List<?> list )
{
JSONObject json = new JSONObject();
JsonConfig config = new JsonConfig();
config.addIgnoreFieldAnnotation( MyAppJsonIgnore.class );
if( list.size() > 0 )
{
JSONArray array = JSONArray.fromObject( list, config );
json.put( "students", array );
}
else
{
//Empty Array
JSONArray array = new JSONArray();
json.put( "students",
array );
}
return json;
}
Now what I want to get is JSON data with following structure: http://jsfiddle.net/bsa3k/1/ (Notice the tempRollNumber field in both array elements).
I was thinking of doing: (The if condition here is used for a business logic)
if(transferStudents.getNewStudentDetails().getRollNumber() == nativeStudents.getNativeStudentDetails.getStudentId()){
json.put("tempRollNumber", transferStudents.getNewStudentDetails().getRollNumber());
}
but this would add tempRollNumber outsite the array elements, I want this JSON element to be part of every entry of students array.
PS: I cant edit the transferStudents class in order to add tempRollNumber field.
Since no one has come up with anything better I'll turn my comments above into an answer.
The best way to handle this is to create an object model of your data and not create the JSON output yourself. Your app server or container can handle that for you.
Though you cannot change the objects you receive in the List you can extend the object's class to add your own fields. Those fields would then appear in the JSON when you marshall it.
Is there a way to add a key to a HashMap without also adding a value? I know it seems strange, but I have a HashMap<String, ArrayList<Object>> amd I want to first be able to create keys as needed and then check if a certain key exists and, if so, put the appropriate value, namely the ArrayList<Object>
Was that confusing enough?
Since you're using a Map<String, List<Object>>, you're really looking for a multimap. I highly recommend using a third-party library such as Google Guava for this - see Guava's Multimaps.
Multimap<String, Object> myMultimap = ArrayListMultimap.create();
// fill it
myMultimap.put("hello", "hola");
myMultimap.put("hello", "buongiorno");
myMultimap.put("hello", "สวัสดี");
// retrieve
List<String> greetings = myMultimap.get("hello");
// ["hola", "buongiorno", "สวัสดี"]
Java 8 update: I'm no longer convinced that every Map<K, SomeCollection<V>> should be rewritten as a multimap. These days it's quite easy to get what you need without Guava, thanks to Map#computeIfAbsent().
Map<String, List<Object>> myMap = new HashMap<>();
// fill it
myMap.computeIfAbsent("hello", ignored -> new ArrayList<>())
.addAll(Arrays.asList("hola", "buongiorno", "สวัสดี");
// retrieve
List<String> greetings = myMap.get("hello");
// ["hola", "buongiorno", "สวัสดี"]
I'm not sure you want to do this. You can store null as a value for a key, but if you do how will be able to tell, when you do a .get("key") whether the key exists or if it does exist but with a null value? Anyway, see the docs.
You can put null values. It is allowed by HashMap
You can also use a Set initially, and check it for the key, and then fill the map.
Yes, it was confusing enough ;) I don't get why you want to store keys without values instead just putting empty arraylists instead of null.
Adding null may be a problem, because if you call
map.get("somekey");
and receive a null, then you do not know, if the key is not found or if it is present but maps to null...
//This program should answer your questions
import java.util.*;
public class attemptAddingtoHashMap { //Start of program
//MAIN METHOD #################################################
public static void main(String args[]) { //main begins
Map<String, ArrayList<Object>> hmTrial = new HashMap<String, ArrayList<Object>>();
ArrayList alTrial = new ArrayList();//No values now
if (hmTrial.containsKey("first")) {
hmTrial.put("first", alTrial); }
else {hmTrial.put("first",alTrial);}
//in either case, alTrial, an ArrayList was mapped to the string "first"
//if you choose to, you can also add objects to alTrial later
System.out.println("hmTrial is " + hmTrial); //empty now
alTrial.add("h");
alTrial.add("e");
alTrial.add("l");
alTrial.add("l");
alTrial.add("o");
System.out.println("hmTrial is " + hmTrial);//populated now
} //end of main
//#############################################################################################################
} //end of class
//Note - removing objects from alTrial will remove the from the hashmap
//You can copy, paste and run this code on https://ide.geeksforgeeks.org/