parsing json using Gson which has objects with same field name - java

I have a json file which has following structure:
{
"Otions": true
"Plastic": ""
"Houses": {
7: {
"name": "Akash Bhawan"
"MemBers": 3
"children": 1
}-
8: {
"name": "Ashiyana"
"memBers": 4
"children": 2
}-
9: {
"name": "Faruks Nest"
"memBers": 5
"children": 1
}-
The objects inside Houses are variable and can increase or decrease accordingly and also change names.
How ever the fieds "name", "members", "children" are the only fields and will always be there
i am using gson to parse
#SerializedName("Otions")
private String Options;
#SerializedName("Plastic")
private String plastics;
#SerializedName("Houses")
private Houses houses;
i want to know if there is a way we can i can store differently named objects in a hashtable or some other way?

If you can't change the structure then you have to make house as Hashmap of int to object. For Example:-
HashMap<int, Object> House;
And that object will have elements like name, memBers, details.

Houses should be a map like this.
private HashMap houses.
Since the 3: indicates an index-structure. Gson will create the nested objects as needed.

Please make "house" as bunch of array instead of objects.
{
"Options": true,
"Plastics": "",
"house": [{
"name": "Akash Bhawan",
"MemBers": 3,
"children": 1
}, {
"name": "Ashiyana",
"memBers": 4,
"children": 2
}, {
"name": "Faruks Nest",
"memBers": 5,
"children": 1
}]
}

You should do something like (as said in my comment):
JSONObject jsonHouses = jsonObject.getJSONObject("Houses");
Iterator<String> keys = jsonHouses.keys(); //this will be array of "7", "8", "9"
if (keys.hasNext()) {
JSONObject singleHouseObject = jsonHouses.getJSONObject(keys.next());
//now do whatever you want to do with singleHouseObject.
//this is the object which has "name", "MemBers", "children"
}

Related

How to convert json values to keys? Basically I want to use value of one key as a "key" and value of other as value

I am writing API in java spring boot. I am consuming below json as response from another API
[
{
"item": "Apple",
"count": 30
},
{
"item": "Orange",
"count": 10
},
{
"item": "Guava",
"count": 4
}
]
I want to convert this to
{
"Apple": 30,
"Orange": 10,
"Guava": 4
}
What is the simplest & efficient way to do this?
Define a class to hold an item
public record Item {
String item;
int count;
}
Deserialise to a List<Item> using your favourite json library (mine is Jackson).
The collect to a map:
Map<String, Integer> map = list.stream().collect(toMap(Item::getItem, Item::getCount));

How to sort and filter a field which is in other indices in elasticsearch?

For example, I have a index named 'student':
{
"id": "100",
"name": "Frank"
}
then there is another index named 'grade':
{
"id": "1"
"score": 95,
"studentId": "100"
}
how can I use one query to get a page of student and sort by score?
Can I use join query to search these two indices like MySQL?
This is what I want to get:
{
"id": "100",
"name": "Frank",
"score": "95"
},
{
...
}
Unfortunately no. Gotta normalize your data since joins are not possible in ES. More at elastic.co/guide/en/elasticsearch/guide/current/relations.html

how to store a arrayList to Map 'string as key and how to retrieve it..!

i wanna retrieve map(ArrayList) according to the key, help me with the code below
public class MainActivity extends AppCompatActivity {
Map<String,ArrayList<Model>> map=new ArrayMap<>(); <----
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......
.....
for (int j=0;j<jsonArray.length();j++)
{
JSONObject tempObj=jsonArray.getJSONObject(j);
String price =tempObj.getString("price");
String product=tempObj.getString("Product");
String qty=tempObj.getString("Qty");
modelList.add(new Model(id,price,product,qty,date));
map.put(key,modelList); <----
modelList.clear();
}
......
......
//here to retrieve that map in the same mainactivity
CODE....??????? <----
here is my json where those months are dynamic (jan, april, jun,...they are not constant).
{
"response": "success",
"servicecode": "134",
"forecast": {
"month": {
"jan": [
{
"id": "1",
"price": "12",
"Product": "1086",
"Qty": "14"
},
{
"id": "2",
"price": "19",
"Product": "1746",
"Qty": "45"
}
],
"april": [
{
"id": "3",
"price": "89",
"Product": "1986",
"Qty": "15"
},
{
"id": "1",
"price": "12",
"Product": "1086",
"Qty": "145"
}
],
"jun": [
{
"id": "81",
"price": "132",
"Product": "17086",
"Qty": "1445"
},
{
"id": "11",
"price": "132",
"Product": "10786",
"Qty": "1445"
}
]
}
},
"message": "Competitor Sales."
}
what i did is i took all the response separately with the key and stored in MAp, now what i want to do is to display the array in according to month in View pager. so tell me map'll do good or any alternative....
You're definitely on the right idea with maps, since you're able to assign each month an object.
However, you may want to consider using a LinkedHashMap instead of an ArrayMap because a LinkedHashMap preserves the insertion order, while ArrayMap's docs does not mention preserving insertion order anywhere.
The reason preserving insertion is important is because the months object in the JSON are presented in the order that you want to display it in. Therefore, if you parse "January" first, it will be guaranteed to be at the front of the Map.
You can declare and initialize a LinkedHashMap as follows:
Map<String, ArrayList<Model>> map = new LinkedHashMap<>();
I am assuming that you have correctly parsed this json into your objects, since you did not say anything in regards to the map being incorrectly populated, and by the placement of your arrows "<-----"
Now, for the code to actually use the Map.
for (String monthName : map.keySet()) {
ArrayList<Model> modelArray = map.get(monthName);
//now do whatever your view pager needs to do with this Model and its fields
for (Model model : modelArray) {
String price = model.getPrice(); //if you have a getter
String product = model.product; //if the field is public
}
}
Notes:
Using the LinkedHashMap's keyset is valid because the documentation guarantees that the keyset will be in insertion order. Also, this SO answer also confirms this fact.
I personally recommend GSON for parsing JSON objects, but since you seem to be okay with the parsing, this is not a big deal.
If you put ArrayMap correctly, you could get it as below:
Model model = map.get("april");
String id = model.id;
String price = model.price;
.....
You should ensure the key variable in your codes is a month name.
Is the month the key of your map?
If so, then you could simply define a list of months and retrieve the values accordingly, something like this:
for(String month: Arrays.asList("jan", "feb", "mar", "apr", "...")) {
if(map.containsKey(month)) { //skip months if not present
//--> code here
Model model = map.get(month);
}
}

Jackson and JSON when the type of a value changes

Using Java 8 and Jackson, I am trying to parse JSON from here:
REST Endpoint
The problem is, there is a single value that sometimes is an empty array and sometimes is a HashMap. I pasted two excerpts below, check out cor_icon in each:
"2630775": {
"id": "2630775",
"label": "breakfast grill",
"description": "breakfast sandwiches, turkey sausage and bacon, home fries, pork sausage and bacon, omelets made to order with whole eggs, egg whites, eggbeaters and assorted fillings",
"zero_entree": "0",
"cor_icon": {
"18": "humane"
},
Or:
"4779080": {
"id": "4779080",
"label": "sweet chili vegan soup\nchicken egg drop soup",
"description": "",
"zero_entree": "0",
"cor_icon": {
"1": "vegetarian",
"4": "vegan"
},
As opposed to:
"2630777": {
"id": "2630777",
"label": "morning pastries",
"description": "assorted danish, muffins, bagels, coffee cakes and tea breads",
"zero_entree": "0",
"cor_icon": [],
"ordered_cor_icon": [],
For my Java setter:
#JsonSetter("cor_icon")
public void setCorIcon(HashMap ci)
{
cor_icon = ci;
}
or better:
#JsonSetter("cor_icon")
public void setCorIcon(HashMap<String, String> ci)
{
cor_icon = ci;
}
This works fine when there is data but when there is not, when I get "cor_icon":[] Jackson throws an exception saying it can not deserialize a HashMap from cor_icon. If I change cor_icon to an ArrayList then when there is data Jackson complains that it can't deserialize an ArrayList from cor_icon.
So what's the trick?
You need to specify type that is valid for both JSON Arrays and JSON Objects. Two obvious choices are java.lang.Object and JsonNode: in first case, you'll get either List or Map (and need to cast); in latter case ArrayNode or ObjectNode.

comparing 2 json effectively

I have a json lets say json 1
[
{
"id": "123",
"testname": "test123",
"name": "John Doe",
"active": true,
"type": "test6"
}
{
"id": "456",
"testname": "test564",
"name": "Ship Therasus",
"active": true,
"type": "test7"
}
.... some 100 entries
]
and json 2 some like below
[
{
"id": "123",
"country": "USA",
"state": "KA",
"age": 24,
"group": "g1"
}
{
"id": "456",
"country": "UK",
"state": "MA",
"age": 28,
"group": "G2"
}
...... 100 entries
]
Now Id is the constant thing between json1 and json2 I want to make a resultant json something like below lets call json3.I want to match the id and get country and state from json2 and append to json 1.I am not looking for code but if i do brute force it takes 100* 100 and hence performance issues. is there any better way to handle this in less complexity?
[
{
"id": "123",
"testname": "test123",
"name": "John Doe",
"active": true,
"type": "test6",
"country":"USA",
"state":"KA"
}
{
"id": "456",
"testname": "test564",
"name": "Ship Therasus",
"active": true,
"type": "test7",
"country":"UK",
"state":"MA"
}
]
The best approach to this problem is O(size(json1 || json2)), because inherently you will have to go through atleast one of the json lists fully to loop through all of the IDs. If you have a constant time lookup (like a hashmap, keyed by the ID), you will be able to pull the information about that specific ID. Honestly I'm not familiar enough with json to suggest a data structure to use, but I know in Java, hashmaps are a frequently used constant time lookup. The best approach would be:
Loop through one json list
Pull out the ID from each entry in this list
Look up the information from the other json list using the same ID
Combine all the information in a resulting json list
Although this answer is somewhat vague, I hope it helps.
Without making any assumptions, I can't think of any way to avoid the O(n^2) complexity based on the given information.
However, if your arrays were already sorted by the object id, you could speed it up by iterating over the array.
var json3 = [];
for(var i = 0; i < json1.length; i++) {
json3.push($.extend({}, json1[i], json2[i]));
}
If you have control over the data structure, an object that is keyed by the id would be much easier to work with than an array:
e.g.
json1 = {
"123": {"testname": "test123", ...},"456": {...}
}
Then your code would simply
var json3 = {};
for(var id in json1) {
json3[id] = $.extend({}, json1[id], json2[id]));
}

Categories