JAVA JSONArray sort in reverse order - java

I have JSON array like this:
[{"BMW": [], "OPEL": [], "Mercedes": []}]
and I want to get
[{"Mercedes": [], "OPEL": [], "BMW": []}]
How can I make like this?

Since JSONObjects are not keeping their order in which you build them (has to do with how it's handled in memory) you should refactor the data.
[{"BMW": [], "OPEL": [], "Mercedes": []}]
to
[{"BMW":[]}, {"OPEL":[]}, {"Mercedes":[]}]
That still won't help you right away though since JSONArray in java doesn't appear to have reverse() method :(
So like I commented: build a new JSONArray in reverse order:
JSONArray newJsonArray = new JSONArray()
for (int i = jsonArray.length()-1; i>=0; i--) {
newJsonArray.put(jsonArray.get(i));
}

A small yet best solution to this is to store the JSON array in reverse order:
JSONArray array = response.getJSONArray("records");
for (int i = array.length()-1; i >= 0; i--) {
// Perform your regular JSON Parsing here
}
You dont need to edit / change your JSON

You have a JSON object, not an array. An object is comprised of key-value pairs, but these pairs are not ordered by key in any way. In fact, the order should not matter - the representation is the same.
From the ECMAScript spec, as copied here: http://interglacial.com/javascript_spec/a-4.html
4.3.3 Object An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive
value, object, or function. A function stored in a property of an
object is called a method.

Related

How do I convert a JsonArray of JsonString to a List of String

This question is scoped to The Java API for JSON Processing (JSR 353).
Given a JsonArray whose elements are JsonString, how can I easily convert this to a List<String> or a Set<String>? For Set<String>, let's assume that the JsonArray contains a unique collection of string values.
Assume I have a JSON object like this:
{
"name" : "James Johns",
"street" : "22 Nancy St.",
"emails" : [
"james#a.com",
"james#b.net",
null,
""
]
}
I want my resulting collection to ignore any null or empty string entries in the emails array.
Let's assume my JsonObject instance has already been created.
JsonObject person = <parse the JSON input>;
JsonArray emails = person.get("emails");
I keep getting stumped on JsonValue and JsonString and trying to get the actual String value. If I use the JsonValue.toString() and JsonString.toString() methods, I get string values that include the double quotes, as if the original JSON was "\"james#a.com\"". I need the string values to be the equivalent JSON value "james#a.com".
Using Java 8, one can easily convert a JsonArray of JsonString to a List like this:
JsonObject person = <parse the JSON input>;
List<String> emailList =
Optional.ofNullable(person.getJsonArray("emails"))
.orElse(JsonValue.EMPTY_JSON_ARRAY) // Use an empty list if the property's value was null
.getValuesAs(JsonString::getString) // Get each JsonString entry as String
.stream() // Turn the collection into a stream for filter/collect
.filter(email -> email!=null && !email.isEmpty()) // Exclude any null/empty entries
.collect(Collectors.toList()); // Create the List
The ofNullable/orElsecombination guarantees I get a JsonArray back, even if that array is empty, thus avoiding any Null Pointer Exception considerations.
The getValuesAs(JsonString::getString) is a JsonArray method that returns a List by applying the JsonString.getString() method to each returned JsonString. The JsonString.getString() method returns the string value "james#a.com" instead of the "\"james#a.com\"" value that the JsonString.toString() method returns.
The stream() method turns the collection into a sequential stream that we can use to filter and collect members of the original collection.
The filter() method applies the Predicate email -> email!=null && !email.isEmpty() to each entry in the stream, throwing out any null entries or entries that are empty strings.
And finally, the collect() method collects the filtered entries into the specified collection type.
To obtain a Set<String>, change the .collect() to use:
.collect(Collectors.toSet())
Once you get accustomed to the Java 8 mechanics, this approach provides a concise, easy to read and understand technique for manipulating collections without the more complicated approach of null/empty checking and using for loops.

How to iterate over json Array having multiple json objects with different header

I am getting an json array from rest webservice in response which is like
[{
"mutualFund":{"fundCode":"XYZ","fundName": "Funds - Global Income
Fund (G)-SGD","isin":"LU0882574725","sedol":"1234"}},
{"brokers":{"fundID":"abcd","fundName":"Funds - Focus
Fund A-USD","isin":"LU0197229882","sedol":"6543"}
}]
I am trying to iterate over all mutualFund arrays attributes to fetch their value. I have tried this code snippet but its returning error --"mutualFund do not exist". In my json file some objects are of mutualfund type and some are of other type with different attributes so I had to iterate and differentiate between both of them . So I cant use getJSONObject(i).
JSONArray jsonArray=new JSONArray(response.getBody());
for(int i=0;i<jsonArray.length();i++){
JSONObject jsonObject=jsonArray.getJSONObject("mutualFund");
}
Based on the classes and methods you're using, I'm assuming you use org.primefaces.json classes. But even if you're using a different API, the logic will be basically the same.
First of all, look at your JSON structure:
[
{
"mutualFund": {
"fundCode": "XYZ",
"fundName": "Funds-GlobalIncomeFund(G)-SGD","isin":"LU0882574725","sedol":"1234"
}
},
{
"brokers": {
"fundID": "abcd",
"fundName": "Funds-FocusFundA-USD","isin":"LU0197229882","sedol":"6543"
}
}
]
It's an array with 2 elements. The first element is an object with just one key (mutualFund) and its value (another object with fundCode and fundName keys). Note that the object has a mutualFund key, and you're trying to get it as if the object itself was a mutualFund. That's what causes the error.
So, to get all mutualFund objects, you need to check every element in the array, and for each element you must check if it has a mutualFund key. Then your code will be like this:
for (int i = 0; i < jsonArray.length(); i++) {
// get object i
JSONObject jsonObject = jsonArray.getJSONObject(i);
// check if object has mutualFund key
if (jsonObject.has("mutualFund")) {
// get mutualFund object and do something with it
JSONObject mutualFund = jsonObject.getJSONObject("mutualFund");
// do something with mutualFund object (you can get values for fundCode and fundName keys, etc)
}
}
Note: if you're using a different JSON API, the methods names might differ (instead of has, some uses containsKey, or get(key) != null, but the logic to find mutualFund objects will be the same).

Can you perform an equals comparison on most but not all class members with GSON's JsonElement

I am writing an unit test with JUnit and I'm wondering if there is a way to perform an assertEquals comparison on it.
I have two JsonElement classes that I would like to compare but I would like to ignore a field in an array property inside the JSON.
My JSON looks like this:
{
"name":"Jon",
"arrayProps":[
{
"careAbout":"123",
"doNotCareAbout":"blablabla"
},
{
"careAbout":"456",
"doNotCareAbout":"blablabla"
},
{
"careAbout":"789",
"doNotCareAbout":"blablabla"
}
]
}
I want to compare all fields apart from the doNotCareAbout elements. Is this possible with GSON when I call:
JsonElement element1 = ...;
JsonElement element2 = ...;
assertEquals(element1, element2);
If it is not, can anybody recommend a suitable library where I can do this type of comparison where I would like exclude some elements?
You could instead write a custom Comparator (or override compareTo) that ignores the element, and verify that assertEquals(compare(element1, element2), 0); or assertEquals(element1.compareTo(element2), 0);. Since you just want to see if they're equal it should be easy to iterate through the elements.
Better to use the comparator so you're not polluting your object with stuff specific to testing.
You can remove the "doNotCareAbout" property from each element in the "arrayProps" array like so:
JsonObject jsonObject = (JsonObject) element;
JsonArray arrayProps = (JsonArray) jsonObject.get("arrayProps");
for (JsonElement arrayProp : arrayProps) {
JsonObject arrayPropObject = (JsonObject) arrayProp;
arrayPropObject.remove("doNotCareAbout");
}
System.out.println(jsonObject); // prints {"name":"Jon","arrayProps":[{"careAbout":"123"},{"careAbout":"456"},{"careAbout":"789"}]}
After doing this, you should be able to to compare the JsonElements in the way that you want.
Alternatively, you could look at using the json-path library to extract just the properties that you want to compare:
String name = JsonPath.read(json, "$.name");
System.out.println(name); // prints Jon
List<String> careAboutProps = JsonPath.read(json, "$.arrayProps[*].careAbout");
System.out.println(careAboutProps); // prints ["123","456","789"]
However, this might not be feasible if the real elements of "arrayProps" have a lot of properties and you only want to exclude a few of them.

Read JSON multi-dimensional array in Java

I have an issue I haven't been able to find a solution to, because it's not quite straight forward I guess...
In my Java program, I receive a string like this (from an existing source, I can't change it, sadly):
["a", 1, "b", 2, ["c", "d", 3], 4]
This string is a valid JSON array (no object, so no key/value pairs!). The content of the array may be totally random (for instance, empty) but can also be multi-dimensional.
I need to find a way to read this in Java. For instance, input.get(4).get(2) should give me 3 in the above example. I don't really care if everything is casted to a string, but I need to find a way to reach the data through indices. Data may also be multiple characters, although my example shows only 1 per element.
How do I accomplish this? Thanks in advance!
Edit; I do know how many elements I expect in the root array, but there are a few dozen cases so I really don't want to program something different for each case
Pick a JSON library. Any of them.
The basic org.json:
JSONArray array = new JSONArray(yourString);
JSONArray arrayTwo = array.getJSONArray(4);
int i = arrayTwo.getInt(2);
Gson:
JsonElement element = new JsonParser().parse(json);
JsonArray array = element.getAsJsonArray();
JsonArray arrayTwo = array.get(4).getAsJsonArray();
int i = arrayTwo.get(2).getAsInt();
Etc, etc.
Using jackson 2.3.0:
import com.fasterxml.jackson.databind.*;
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree("[\"a\", 1, \"b\", 2, [\"c\", \"d\", 3], 4]");
int i = node.path(4).path(2).intValue();
System.out.println(i);
prints
3
Javadoc for JsonNode is here.

Passing json array in a key value pair

I want to know how to pass the json array as key in a json object.
{
"name" :"Sam",
"grades": [{"maths": "A", "result":"pass"}, {"science": "B", "result":"pass"}]
}
I couldn't pass both the values to 'grades' in jSONObject. I Looped it. But, it simply overwrites the values.
It seems like you are doing something like:
obj.put("grades", mathGrade);
obj.put("grades", scienceGrade);
Where the scienceGrade just overwrites mathGrade.
What you should be doing is using an intermediate array object:
JSONArray grades = new JSONArray();
grades.put(mathGrade);
grades.put(scienceGrade);
obj.put("grades", grades);

Categories

Resources