I'm a beginner Java and Gson user and have been able to apply it to my needs. I now have some JSON data that I need to parse into a spinner as follows:
{
"lang":[
"arabic",
"bengali",
"dutch-utf8",
"eng_root",
"english",
"english-utf8",
...
],
"themes":{
"blue":{
"chinese_ibm500":1,
"spanish":1,
"bengali":1,
"japanese":1,
"english":1,
"russian":1,
"french-utf8":1,
"eng_root":1,
"arabic":1,
"spanish-utf8":1,
"portuguese":1,
...
},
"green":{
"eng_root":1,
"engmonsoon":1,
"english":1
...
},
"red":{
"chinese_ibm500":1,
"spanish":1,
"bengali":1,
...
}
}
}
So from this JSON I need 2 things:
1) the array under lang is dynamic as for its the languages installed on the server. How could I get all the entries?
I have a class as follows but im stuck as to what I should do after I return lang
public class ListData {
private List<Language> lang;
public List<Language> getLang {
return lang;
}
public static class Language {
???
}
}
2) after understanding 1 I might be able to figure this one out. Under themes are colors which again can be more or less {purple, orange, whatever}. I just need a list of those themes, as far as I'm concerned I don't need to know the languages for each.
Feel like this question is turning into a book. I have searched SO extensively and hate asking questions but I'm pretty stumped. Thanks in advance.
1) In order to get the "lang" array, just modify
private List<Language> lang;
for
private List<String> lang;
Since the elements inside "lang" array are all strings, you don't need any class Language to store those values, they'll be parsed correctly as strings. And it doesn't matter how many strings the array contains...
2) In order to parse "themes", you have to notice that it's not an array [ ], but an object { }, so you do need to parse it with some object, and the most suitable class here is a Map like this:
private Map<String, Object> themes;
Note: as you said that you don't need the data under "blue", "green", etc... you can just Object as the value type in the map, otherwise you'd need some class...
Using a Map here allows you to have an arbitrary number of themes in your JSON response.
So in summary, you just need a class like:
public class ListData {
private List<String> lang;
private Map<String, Object> themes;
//getters & setters
}
and parse your JSON with:
Gson gson = new Gson();
ListData data = gson.fromJson(yourJsonString, ListData.class);
Your list of langs will be under:
data.getLang();
and your list of themes will be under:
data.getThemes().keySet();
I suggest you to take a look at Gson documentation. It's quite short and clear and you'll understand everything much better...
Related
can some one explain me how to get all categories value from
"categories":[{"1":1,"2":"orange","3":"mango","4":"guava","5":5,"6":6}]
result my like this 1 = 1, and 2 = orange,
what must i do i am stuck in here
public RealmList<CategoryRealm> categories;
or
p.categories = new RealmList<>();
can some one explain to me what must i do in the next method i am stuck tried searching but so damn hard to learn its diferent.
Use GSON library.
Create an object that matches your structure. I'm assuming you have a structure of
{
"categories"://the rest of the stuff here
}
class MyParentObject{
#SerializeName("categories")
ArrayList<String> myList;
}
Then use GSON to create it
MyParentObject obj = (MyParentObject)getGson().fromJson(json, classType);
and your done.
If the base is just the categories string then your json is badly formatted and you may have to do a subString call to get starting index of "[" and go from there into json management.
I am trying to parse a JSON .txt file into a JAVA object using GSON. The JSON file has the following structure:
{
"event0" : {
"a" : "abc",
"b" : "def"
},
"event1" : {
"a" : "ghi",
"b" : "jkl",
"c" : "mno"
}
}
I have read the text file into a String called dataStr. I want to use the fromJson method to capture the events into the following JAVA class:
public class Event {
private String a;
private String b;
private String c;
public Event() {}
}
The problem is that the JSON might have one extra field "c" in some of the elements. I want to parse all the events into Event class objects, and for the cases where there is no "c" field, I want to make it null or zero in my object. It is not known beforehand which of the elements will have the "c" field.
Specifically, I was not able to figure out how to handle one extra field in some of the JSON elements. I want to do something along the lines of:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
But I am stuck with first, how to iterate over the events in the Json file, and secondly, how to handle some occasional missing fields into the same Event object. I would really appreciate a kick in the right direction. Thank you all.
I am fairly new to JSON parsing, and might have missed something in the following answers:
Using Gson to convert Json into Java Object
Mapping JSON into POJO using Gson
Using gson to parse json to java object
Parse JSON into a java object
How to parse a json file into a java POJO class using GSON
I'm not sure if I understood your question right. As per my understanding, you are trying to convert a json object with an extra field which is not available in the java class. Frankly, I don't understand why you want that or if it's possible to start with. You can have a workaround by converting the json to Map.
Map map = gson.fromJson(jsonString, Map.class);
Gson automatically do that for you.
So, if you have a class "Alpha" with 3 fields ("a", "b" and "c") and you try to work on a json object that has 2 fields with names that match with Alpha's "a" and "b", Gson will fill "a" and "b" with json file's value and "c" will automatically set as null.
So, in your case, if you write this:
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
And in your json there are events with only 2 fields (that match with any Event's class fields) and events with all fields set, you will get a list of Events with no errors. Maybe you'll get some fields null, but the code will work.
I hope to be helpful! Ask for further informations, if you want to!
EDIT
Note that your json file has not to be .txt but .json instead!
First I believe your JSON should look like this:
{
"events": [
{
"name": "event0",
"a": "abc",
"b": "def"
},
{
"name": "event1",
"a": "abc",
"b": "def",
"c": "mno"
}
]
}
This will need two classes for your model:
public List<Event> events = null;
public class Event {
public String name;
public String a;
public String b;
public String c;
}
And then then with GSON
Events events = gson.fromJson(jsonData, Events.class);
Also I recommend to always use an online validator for JSON so you are sure your JSON structure is correct before coding against it.
https://jsonlint.com/
Or for formate the JSON:
http://jsonprettyprint.com/
Also this website can create the Java classes for you from either a JSON Schema or by using an example file.
http://www.jsonschema2pojo.org/
Try the below code snippet:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, new TypeToken<ArrayList<Event>>(){}.getType());
In the source code of Gson has a very clear explain
I have JSON like this:
# "trig_cond": {
# "_and": {
# "param1": ["op", "value1"],
# "param2": ["op", "value2"], ...
# },
# "_or": {
# "param1": ["op", "value1"],
# "param2": ["op", "value2"], ...
# }
# }
the "_and"/"_or" part has an undetermined number of keys that map to list objects (each containing two items).
How can I deserialize this into a java object? I've looked at various custom deserialization options but I don't understand how to do it for this example json.
There are few different options you can take depending on your requirements. One of the simplest solutions you can take when you have an unknown number of keys is to simply leave these parts of your POJO as JSONObject.
For example, this POJO would meet your requirements to deserialize the JSON into a java object, and still provide the flexibility you are after.
public class SamplePojo {
TrigCond trig_cond;
public static class TrigCond {
JsonObject _and;
JsonObject _or;
}
}
You could also split them into different files if you prefer.
Also, since in your example, you know what types of values are contained with these param1 and param2 array elements, you could instead using a Map
Here is another example which you may prefer:
public class SamplePojo {
TrigCond trig_cond;
public static class TrigCond {
Map<String, String[]> _and;
Map<String, String[]> _or;
}
}
Let me know if I understood your question correctly!
I receive a List<org.apache.avro.generic.GenericRecord> with the data contents as shown below (JSON notation used for clarity). How can I best hold these record types using Java?
Record 1:
[
{
"serial_no" : "x",
"data1" : "d"
},
{
"serial_no" : "y",
"data2" : "d2"
},
............................MANY MORE
]
Record 2:
[
{
"id":"x",
"type":"A"
},
{
"id" : "x",
"type" : "B"
},
{
"id" : "y",
"type" : "A",
},
{
"id" : "y",
"type" : "B"
}
]
As you see here, each serial number has two records in record2. serial_no in record1 is same as id in record2.
My Goal is:
Fatsest way to find these two records.
Solution I think:
Create a map like
map.put("x", [map.put("A",List), map.put("B",List)]);
But I feel like, its a complex structure. Because map contains list of maps[each map is Map<String,List<Map<String,String>>>].
Any suggestions?
EDIT
Each entries in records are avro GenericRecord
It looks as if you are trying to parse JSON using Java. Why not use a specific library for that?
Like the basic http://www.json.org/java/ or Google's https://github.com/google/gson
Otherwise, I do not think that the complex structure you are proposing is especially slow. You might want to design your own object class to hold the data if you think it is more efficient or easier to get to the data.
EDIT
Based on your question I assumed JSON was the format you received it in, sorry.
I would just create a wrapper for GenericRecord, or subclass it. Then add the methods that you need to extract the data, or make it Comparable for sorting.
Something along the lines of
public class MyRecord extends GenericRecord implements Comparable<MyRecord>
{
// Determine the type
public int getType()
{
if ( this.get( "id") != null )
return 2;
return 1;
}
// Add methods that allow you to retrieve the serial field from any of the two record types
public String getId()
{
if ( this.get( "id") != null )
return (String)this.get("id");
return (String)this.get("serial_no");
}
// add comparator methods that will allow you to sort the list, compare based on Id, etc
#Override
public int compareTo(MyRecord another)
{
// Just a simple example
return this.getId().compareTo( another.getId() );
}
}
Define classes for repeated entries:
class SerialNoData {
String serialNo;
Object data;
}
and
class IdType {
String id;
String type;
}
; once parsed put the instances into arrays or Lists to get the desired format.
How complex the map is doesn't really make a difference for the speed. Depending on the type of Map you use getting a list of records will be constant time (with a reasonably small overhead). Finding something in the sublists will then be O(n), since you need to iterate through the list and look at all the Maps.
Define following classes
class Serial{
String serial-no;
String data;
List<IdType> idTypes;
}
class IdType{
String id;
String type;
}
After that you can use jackson or any kind of JSON processing library.
I want to create a multidimensional array where each of the nodes will have the following details:
Place Name ex: "Mysore" , "Bangalore"
Icon name ex: "waterfall", "wildlife"
Place Distance ex: "200", "123"
Which is the best way to do this when I have over 30 values ?
Example:
"Bangalore", "200", "city"
"Mysore", "100", "historic"
I am trying to populate a list array in Android where each row has three details - name, icon, distance so I want to temp populate that data in my java class.
Don't use a multidimensional array. Use a simple array (or List) of objects:
public class Place {
private String name;
private String icon;
private int distance;
// constructor, methods skipped for brevity
}
...
private Place[] places = new Place[10];
// or
private List<Place> places = new ArrayList<Place>();
Java is an OO language. Learn to define and use objects.
I think best option is create custom defined object.
Class TestObject
{
String Place,Icon,Distance;
// Setter and Getter method
}
// Create object of class. Store your value using setter and getter method
and save object into list
List<TestObject> test = new ArrayList<TestObject>();
test.add(testObject); //
Create a class with the attributes that you want in an element.
now you can create an array of objects of this class.
class Place {
private String name;
private String icon;
private int distance;
public Place(String name,String icon,int distance){
this.name=name;
this.icon=icon;
this.distance=distance;
}
}
Place places[]=new Place[10];
places[0]=new Place("Mysore","wildlife",123);
and so on
beware of instantiating the objects else you will endup getting NullPointerException
If you don't want to create a separate class . You can also use JSON for your purpose.
JSON object is light weight and can manage aaray data very easily.
Like :
JSONObject jo = new JSONObject();
JSONArray ja = new JSONArray();
ja.put("Mysore");
ja.put("wildlife");
ja.put(123);
jo.add(KEY, ja); // Adding array to JSON Object with key [KEY can be any unique value]
JSON are easy to read and manageable.
It provides lots of functionality rather than array.