How can i use a constructor of a generic class - java

i got multiple classes which do basicly the same. I pass a JSONObject in the constructor an it sets some variabes.
Now i got some other classes which create those first classes and add them to a ArrayList. Now i want to merge the second classes to one using generics.
This is what I want to do:
public class Data<T> {
public ArrayList<T> data;
public Data(String response1) {
data = new ArrayList<T>();
JSONArray ja;
try {
ja = new JSONArray(response1);
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
data.add(new T(jo));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
but it doesnt let me create an Instance of T with
new T(jo);
Would be nice if someone can help me

There is a standard trick for this situations: pass Class<T> along with the String data into the call, and add a setter for the JSONObject. This would let you call a parameterless constructor, like this:
interface WithJson {
void setJson(JSONObject jo);
}
public class Data<T extends WithJson> {
public Data(String response1, Class<T> type) {
data = new ArrayList<T>();
JSONArray ja;
try {
ja = new JSONArray(response1);
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
T obj = type.newInstance();
object.setJson(jo);
data.add(obj);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
The Class<T> has been modified in Java 5 to let you use it as a factory for the instances of that class. The call of type.newInstance is checked statically for type safety. The addition of the interface WithJson lets you call setJson method on the instances of T in a way that the compiler can check statically.
When you construct Data<T>, you need to pass the class being created, like this:
Data<MyContent> d = new Data(jsonString, MyContent.class);

Use a generic factory interface.
public interface Factory<T>
{
public T createFromJSONObject( JSONObject jo );
}
And now a modified constructor:
public Data(
String response1,
Factory<T> factory
) {
data = new ArrayList<T>();
JSONArray ja;
try {
ja = new JSONArray(response1);
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
data.add( factory.createFromJSONObject( jo ) );
}
} catch (JSONException e) {
e.printStackTrace();
}
}

Related

How to put in array the children of the children

private static JSONArray getListOfChildPagesAsJSON(Page page) {
JSONArray pagesArray = new JSONArray();
try {
Iterator<Page> childPages = page.listChildren();
while (childPages.hasNext()) {
Page childPage = childPages.next();
JSONObject pageObject = new JSONObject();
pageObject.put(childPage.getTitle(), childPage.getPath());
pagesArray.put(pageObject);
}
} catch (JSONException e) {
LOG.error(e.getMessage(), e);
}
return pagesArray;
}
So that not only the children of the transferred page put into array, but also the children of the children.
This is a classical case for recursion, like reading directoy tree on filesystem. My suggestion is as follows:
First step: Change the scope of variable JSONArray pagesArray = new JSONArray(); from function to class scope.
public MyClass {
private JSONArray pagesArray = new JSONArray();
...
}
Step two: Change return value to void and the modifier of your function by removing static.
private void getListOfChildPagesAsJSON(Page page) { }
Step three add the missing recusion to your its body.
//JSONArray pagesArray = new JSONArray();
try {
Iterator<Page> childPages = page.listChildren();
while (childPages.hasNext()) {
Page childPage = childPages.next();
JSONObject pageObject = new JSONObject();
pageObject.put(childPage.getTitle(), childPage.getPath());
//Add the created object to your array which is class variable
this.pagesArray.put(pageObject);
//--Check for each single page for child pages again
Iterator<Page> childPagesOfChildpage = childPage.listChildren();
while (childPagesOfChildpage.hasNext()) {
getListOfChildPagesAsJSON(childPagesOfChildpage.next());
}
//--
}
} catch (JSONException e) {
LOG.error(e.getMessage(), e);
}
Note: The check childPage.hasChild() does not work here, because the node jcr:content is a valid child of passed page.

Getting value from json item in java

I have a json file, for example:
{
"A":"-0.4",
"B":"-0.2",
"C":"-0.2",
"D":"X",
"E":"0.2",
"F":"0.2",
"J":"0.3"
}
I want return each element of a list json when I call it via my function.
I did a function to do this:
public JSONObject my_function() {
JSONParser parser = new JSONParser();
List<JSONObject> records = new ArrayList<JSONObject>();
try (FileReader reader = new FileReader("File.json")) {
//Read JSON file
Object obj = parser.parse(reader);
JSONObject docs = (JSONObject) obj;
LOGGER.info("read elements" + docs); // it display all a list of a json file like this: {"A":"-0.4","B":"-0.2","C":"-0.2","D":"X","E":"0.2","F":"0.2","J":"0.3"}
for (int i = 0; i < docs.size(); i++) {
records.add((JSONObject) docs.get(i));
System.out.println((records)); // it return null
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
LOGGER.info("The first element of a list is:" +records.get(0)); // return null
return records.get(0);
How can I change my function to return the value of each element in a json file.
For example, when I call my_function:
my_function.get("A") should display -0.4
Thank you
First you need a Class for mapping
public class Json {
private String a;
private String b;
private String c;
private String d;
private String e;
private String f;
private String j;
//getters and setters
}
Then in your working class
ObjectMapper mapper = new ObjectMapper();
//JSON from file to Object
Json jsn = mapper.readValue(new File("File.json"), Json.class);
then you can use that object in a usual way...
here is the dependency I used
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
Reference
In Java you can use only class`s methods, as I know.
If you want to get your second element by its first, you should in your class create 2 methods like
class Main {
Map<String, String> records = new HashMap<>();
public JSONObject my_function() {
// your realization where you should insert your pairs into Map.
}
public String get(String firstElement){
return map.getValue(firstElement);
}
}
class someOtherClass {
Main main = new Main();
main .my_function();
main .get("A");
}

Split jsonarray data into multiple list using array value

I want to split an ArrayList according to the existing data, Like as
category etc.
I try nested for loop and add them into list.but It's not working.
String url = "http://27.147.169.230/UpSkillService/UpSkillsService.svc/" + "GetCNCCourseDefByorg/" + 1 +"/" +1;
Ion.with(getApplicationContext())
.load("GET",url)
.setBodyParameter("","")
.asString()
.setCallback(new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
Log.d("Result",result);
try {
JSONObject obj =new JSONObject(result);
JSONArray jsonArray = obj.getJSONArray("GetCNCCourseDefByorgResult");
//Arrays.sort(new JSONArray[]{jsonArray});
if(obj.isNull("GetCNCCourseDefByorgResult"))
{
Toast.makeText(getApplicationContext(),"No Course Found",Toast.LENGTH_SHORT).show();
}
else if (!obj.equals(null)) {
String cata="";
Log.d("Resul3", jsonArray.toString());
for (int i = 0; i < jsonArray.length(); i++) {
final CourseCatagory catagoryModel = new CourseCatagory();
JSONObject course = jsonArray.getJSONObject(i);
CourseList courselist = new CourseList();
if(cata!=course.getString("CategoryName"))
{
Log.d("Catagory",cata);
catagoryModel.setCategoryName(course.getString("CategoryName"));
arrayListcatagory.add(catagoryModel);
for (int j=0;j<jsonArray.length();j++)
{
JSONObject cat1 = jsonArray.getJSONObject(j);
cata=cat1.getString("CategoryName");
Log.d("cat",cata);
if(cat1.getString("CategoryName")==course.getString("CategoryName"))
{
courselist.setCourseName(cat1.getString("CourseName"));
courselist.setCourseCode(cat1.getString("CourseCode"));
courselist.setWishFlag(cat1.getInt("WishFlag"));
Log.d("Course",cat1.getString("CourseName"));
arrayListcourse.add(courselist);
}
else {
}
}
}
catagoryModel.setCourseList(arrayListcourse);
}
adapter.notifyDataSetChanged();
}
} catch (JSONException e1) {
e1.printStackTrace();
}
}
});
}
`
I want as catagory, under catagory course shown which match catagory name.
Accounting>Introduction Accounting,Advance accounting
Finance>Introduction Finance
You can Use HashMap<String,ArrayList<CategoryDetails>> to resolve your Problem.
First Create CategoryDetails POJO class
class CategoryDetails {
private courseName;
private courseCode;
private wishFlag;
//make setter and getter methods for above fields.
}
Then use category Name as key in HashMap to differentiate as mentioned in first line of my answer.
Map<String,ArrayList<CategoryDetails>> listCategory = new HashMap<String,ArrayList<CategoryDetails>>;

Hashmap clear values

I have this code. When i clear ArrayList, values in HashMap clear too. How can i save data?
public class Stations extends AppCompatActivity {
public static Map<String, ArrayList<String>> cities = new HashMap<>();
...
public void parseFrom() {
cities.clear();
ArrayList<String> citiesList = new ArrayList<>();
try {
JSONObject jObject = new JSONObject(loadJSON());
JSONArray jArray = jObject.getJSONArray("citiesFrom");
String countryTitle = null;
for (int i = 0; i < jArray.length(); i++) {
JSONObject jsonObject = jArray.getJSONObject(i);
if ((countryTitle != null) && (!countryTitle.equals(jsonObject.getString("countryTitle")))) {
cities.put(countryTitle, citiesList);
citiesList.clear();
}
countryTitle = jsonObject.getString("countryTitle");
citiesList.add(jsonObject.getString("cityTitle"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
When I use citiesList.clear();all values are clearing, but keys still "alive".
This is because they have the same reference in memory.
Try doing this:
cities.put(countryTitle, new ArrayList<String>(citiesList));
But, if what you really want is to remove it from the hashmap, you'll have to call cities.remove(countryTitle) instead of only clearing the array of cities.

Deserialize classes with same interface using GSON

I have an interface (called Content) and a couple of classes that implement that interface (e.g. ContentVideo, ContentAd...). I receive a JSON Object that contains a list of those objects. I started out deserializing those objects manually in seperate classes, but recently came across GSON, which would simplify this process immensely. But I'm not sure how to implement this.
Here's ContentVideoJSONParser
public ArrayList<ContentVideo> parseJSON(String jsonString) {
ArrayList<ContentVideo> videos = new ArrayList<>();
JSONArray jsonArr = null;
Gson gson = new Gson();
try {
jsonArr = new JSONArray(jsonString);
for(int i = 0; i < jsonArr.length(); i++) {
JSONObject jsonObj = jsonArr.getJSONObject(i);
ContentVideo cv = gson.fromJson(jsonObj.toString(), ContentVideo.class);
videos.add(cv);
}
} catch (JSONException e) {
e.printStackTrace();
}
return videos;
}
ContentAdJSONParser looks exactly the same, except for returning an ArrayList of ContentAd objects and this line to retrieve the object:
ContentAd ca = gson.fromJson(jsonObj.toString(), ContentAd.class);
What's the easiest way to combine those to classes into one? Note: one JSON object only contains one class, either ContentVideo or ContentAd. They are not mixed like in other SO questions, which would require a TypeAdapter.
This seems to be a straightforward problem but I can't figure it out. Thanks for your help.
Something like this perhaps?
public <T extends Content> ArrayList<T> parseJSON(String jsonString, Class<T> contentClass) {
ArrayList<T> contents = new ArrayList<>();
JSONArray jsonArr = null;
Gson gson = new Gson();
try {
jsonArr = new JSONArray(jsonString);
for(int i = 0; i < jsonArr.length(); i++) {
JSONObject jsonObj = jsonArr.getJSONObject(i);
T content = gson.fromJson(jsonObj.toString(), contentClass);
contents.add(content);
}
} catch (JSONException e) {
e.printStackTrace();
}
return contents;
}

Categories