JSONObject vs JARRAY getting array length - java

I have a JSONObject that I pass to a method to get processed into ArrayLists.
{
"set0" :
{
"title" : "Do you win?",
"answer" : "1",
"imgUrl" : "imag",
"id" : "1"
},
"set1" :
{
"title" : "Did you loose?",
"answer" : "1",
"imgUrl" : "imag",
"id" : "2"
}
}
The method is structured like this:
questions(JSONObject result){
// initialization
for(int i=0;i < result.length();i++){
question_list.add(result.getJSONObject("set"+i).getString("title"));
answer_list.add(result.getJSONObject("set"+i).getString("answer"));
img_list.add(result.getJSONObject("set"+i).getString("imgUrl"));
question_batch.add(result.getJSONObject("set"+i).getInt("id"));
}
// rest of code
}
I normally see the jsonarray being used for the loop condition and not the jsonobject itself, when my jsonobject gets bigger but in the same structure as posted above will result.length() start to yield a wrong result and is this an incorrect implementation for someone who will want to iterate through their jsonobject?

I'm not sure if your implementation is "incorrect", but this is how I generally iterate through JSON.
int i = 0;
boolean continue = true;
while (continue){
if (result.has("set" + i){
JSONObject set = result.get("set" + i.toString());
if (set.has("title"){
question_list.add(set.getString("title");
}
if (set.has("answer"){
answer_list.add(set.getString("answer");
}
if (set.has("imgUrl"){
image_list.add(set.getString("imgUrl");
}
if (set.has("id"){
question_batch.add(set.getInt("id");
}
i++;
}else{
continue = false;
}
}
This is a little more efficient because you don't have to create a new JSON object everytime you want to pull data out.
Also I would make a new class to handle the JSON objects, and make the array list of that type, so you only have to add one object for each iteration. This way, you can be sure that your questions/answers/imageURLs/id's are all kept together. Like this:
JSONObject set = result.get("set" + i.toString());
QuestionObject newQuestion = new QuestionObject();
if (set.has("title"){
newQuestion.setTitle(result.getString("title");
}
if (set.has("answer"){
newQuestion.setAnswer(result.getString("answer");
}
if (set.has("imgUrl"){
newQuestion.setImageURL(result.getString("imgUrl");
}
if (set.has("id"){
newQuestion.setID(result.getInt("id");
}
questionList.add(newQuestion);
Also, in case you didn't notice, you can directly parse integers using json.getInt() for your "id" field instead of string.

You might want to have a look to Jackson also. That is also quite straightforward, and your code might benefit from using it.

Related

How to check if a value exists in a JSON Array for a particular key?

My JSON array file:
[
{
"setName": "set-1",
"testTagName": "Test1",
"methodName": "addCustomer"
},
{
"setName": "set-1",
"testTagName": "Test2",
"methodName": "addAccount"
},
{
"setName": "set-2",
"testTagName": "Test3",
"methodName": "addRole"
}
]
I use Java. I have the above JSON Array in a Gson object.
How do I iterate through this Gson array to check if a particular method name (eg: addRole), exists in the array for the key "methodName" in any of the objects of the JSON array? I am expecting true/false as a result.
I checked the GSON doc - (https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/JsonObject.java#L141)
The has method seems to check for the key. I am looking for a method that can iterate through the objects of the array and check if a particular value exists for a specific key.
How can I achieve this?
First you need to deserialize the JSON code to a JsonArray in this way:
JsonArray jsonArr = gson.fromJson(jsonString, JsonArray.class);
After that you can create this method:
public boolean hasValue(JsonArray json, String key, String value) {
for(int i = 0; i < json.size(); i++) { // iterate through the JsonArray
// first I get the 'i' JsonElement as a JsonObject, then I get the key as a string and I compare it with the value
if(json.get(i).getAsJsonObject().get(key).getAsString().equals(value)) return true;
}
return false;
}
Now you can call the method:
hasValue(jsonArr, "methodName", "addRole");
You can get the JSON in a JsonArray and then iterate over the elements while checking for the desired value.
One approach is suggested by #Crih.exe above. If you want to use Streams, you can convert the JsonArray into a stream and use anyMatch to return a boolean value
...
// Stream JsonArray
Stream<JsonElement> stream = StreamSupport.stream(array.spliterator(), true);
// Check for any matching element
boolean result = stream.anyMatch(e -> e.getAsJsonObject()
.get("methodName").getAsString().equals("addRole"));
System.out.println(result);
...

javax.json.JsonArrayBuilder strange behavior

I am creating JsonArrayBuilder using JsonBuilderFactory and trying to add two JsonObject into it.
After the loop is over, JsonArrayBuilder.build method is returning same (duplicates) objects.
Example:
JsonBuilderFactory factory = Json.createBuilderFactory(null);
JsonArrayBuilder array_builder = factory.createArrayBuilder();
for(int i=0;i<2;i++)
{
JsonObjectBuilder json_Builder = factory.createObjectBuilder();
json_Builder.add("Key", "Val_"+i);
array_builder.add(json_Builder.build());
}
JsonArray json_Array = array_builder.build(); // this producing same two json objects
//with same key and value
System.out.println("Result - "+ json_Array.toString());
Output :
[
{
"Key":"Val_1"
},
{
"Key":"Val_1"
}
]
Getting this wired behavior on some machine, I checked the machine with this behavior installed openJDK 1.8.0_212 ( hope this is not the problem ).
Can you please help me understand why this objects getting duplicate ?

JSON construction

I am new to JSON and getting confused everytime I create a new one.
I am trying to create a JSON array like this :
{
"id":"2003",
"HouseMD" :
{
"Doctor_1": "Thirteen",
"Doctor_2" : "Chase"
"Doctor_n" : "Someone"
}
}
Basically I am trying to add info dynamically from Doctor_1 to Doctor_n" in a for loop. and if I use a JSON Object I am only getting the last value when I finally print it.
How do I get something that I want?
Any help appreciated.
Thanks.
JSON arrays look like this:
{ "id":"2003", "HouseMD" : [{ "Doctor_1": "Thirteen"}, {"Doctor_2" : "Chase"}, {"Doctor_n" : "Someone" }]}
Notice the square bracket that surrounds each JSON object in the array.
Here is the link to the JSON website, which can offer more info:
JSON
Note that in order for the code below to work, you will also need the JSON library, which you can easily download from here Download Java JSON Library
I don't know the approach you are using, but based on the format you want, I would do something like this:
JSONObject data = new JSONObject();
data.put("id", "2003");
JSONObject doctors = new JSONObject();
//here I suppose you have all doctors in a list named doctorList
//and also suppose that you get the name of a doctor by the getName() method
for (int i = 0; i < doctorList.size(); ++i)
{
doctors.put("Doctor_" + (i+1), doctorList.get(i).getName();
}
data.put("HouseMD", doctors);
//then you could write to a file, or on screen just for test
System.out.println(data.toString());
However, I feel you need to become more comfortable with JSON, so try starting here.

Parsing JSONObject but running into NullPointer exception

I am parsing a JSONObject which I extract from a Mongo DB. The number values map to java.lang.number objects according to the documentation, However, I get an error when I try to make the following declarations, specifically in the first System.out.println(value.floatVlaue()).
//For data
int counter = 0;
float score = 0;
Number value = 0;
while(cur.hasNext()){
JSONObject jsonObj = (JSONObject) JSONValue.parse(cur.next().toString());
metricsIterator = ((JSONObject)((JSONObject)((JSONObject)((JSONObject)jsonObj.get("level_1")).get("level_2")).get("level_3")).get("metrics")).keySet().iterator();
while(metricsIterator.hasNext()){
System.out.println(metricsIterator.next().toString());
value = (Number) jsonObj.get(metricsIterator.next());
System.out.println(value.floatValue());
System.out.println(value.toString());
someLogic(value.doubleValue(), ((Number)jsonObj.get("long")).intValue(), start, end, days);
}
}
I think the problem line definitely comes from the value = (Number) jsonObj.get(metrics Iterator.next())
the Json im parsing looks like this
{ "_id" : "9223370663181869423_cnn_1" ,
"long" : 1373672925000 ,
"level_1" :
{ "level_2" :
{ "level_3level" :
{ "metrics" :
{"key1" : 0.003333333333333334 ,
"key2" : 0.005833333333333334 ,
"key3" : 0.005833333333333334 ,
"key4" : 0.009166666666666667 ,
"key5" : 0.1391666666666667 ,
"key6" : 0.1241666666666667 ,
"key7" : 0.01666666666666667
}
}
}
}
}
Thanks so much for any help at all!
Iterators can only be traversed once. This means that once you do metricsIterator.next() in System.out.println(metricsIterator.next().toString());, you end up using up that value and when you call .next() again in value = (Number) jsonObj.get(metricsIterator.next()); you get the value after the one that you are expecting, in other words you skip a value.
As a result when you hit the last value, the next value is null which results in the null pointer.
Try removing the sysout before assignment to value, it should solve the nullpointer.
you are doing twice the metricsIterator.next()
first: System.out.println(metricsIterator.next().toString());
second: value = (Number) jsonObj.get(metricsIterator.next());
then you get to the end without checking if hasNext()

Parsing JSON String

I have this JSON file that is read and stored in a String called jsonString and it looks like this:
{
"position":1,
"team_id":10260,
"home":
{
"played":18,
},
},
{
"position":2,
"team_id":8456,
"home":
{
"played":12,
},
},
Code for parsing:
JSONObject obj = new JSONObject(jsonString);
Iterator it = obj.keys();
while(it.hasNext()){
String s = it.next().toString();
System.out.print(s + " " + obj.getString(s) + " ");
}
Output is: position 1 home {"played":18} team_id 10260
So it doesn't read the rest of the file. Can you tell me what is the problem? And also, why home {"played":18} is printed before team_id 10260?
If you look at the way your brackets are organized, you can see that your String actually contains several JSON objects, and the construction stops after the first complete one.
As for your second question, Iterators seldom have a guaranteed order, so you can't make any assumptions about which order the elements will be returned in.
The order will be dependent on the type of Map that JSONObject uses; could be indeterminate, or could be by the key's codepoint, or could be in order read, depending on, e.g. HashMap, TreeMap or LinkedHashMap.
Other than that, there are two objects serialized and JSONObject has apparently just stopped after the first one. You may need to wrap the entire input in a set of { }.

Categories