Strange results!!! Is it because of json? or what? - android

I have a class called GradeModel2 that has 2 members: grade (as string) and sections (as list of strings). I am trying to get my GradeModel2s data from a json string that I've read from a server.
List<GradeModel2> gradeList = new ArrayList<>();
List<String> sectionsList = new ArrayList<>();
JSONObject jo = new JSONObject(json);
JSONArray grades = jo.getJSONArray("grades");
for (int i=0;i<grades.length();i++){
sectionsList.clear();
JSONObject grade = grades.getJSONObject(i);
JSONArray sections = grade.getJSONArray("sections");
Log.e("length",sections.length()+"");
for (int k=0;k<sections.length();k++)
sectionsList.add(sections.getString(k));
gradeList.add(new GradeModel2(grade.getString("grade"), sectionsList));
}
/**************/
for (GradeModel2 grade : gradeList) {
List<String> ss = grade.getSections();
for (String s : ss)
Log.e("section",grade.getGrade()+" : "+s);
}
/**************/
The retrieved json string looks like the following:
{"id":"596","privileges":"T","grades":[{"grade":"1","sections":["A","B","C"]},{"grade":"3","sections":["A","B"]},{"grade":"7","sections":["A"]},{"grade":"9","sections":["B"]},{"grade":"10","sections":["A"]}]}
The problem is that the sections list of all GradeModel2 objects is of length 1 and value A !!!
the first Log.e, one line before the inner for loop, shows that the length of the first item of the list is 3 (A,B, and C (see the json)). However, I am trying to print all the sections of each GradeModel2 object in the inner for loop in the second block, but all I see section A for all the grades!!! (see the pic)
the result of the two Log.e
What is going on? Why is this happening?

Your problem is in sectionsList. You are trying to reuse same object, so this line of code new GradeModel2(..., sectionsList); will just add reference to the same sectionsList. And because of sectionsList.clear(); you see "A" from last json section ({"grade":"10","sections":["A"]}) To fix this, you have to create new array each time in your for loop. Something like this:
for (int i = 0 ; i < grades.length() ; i++){
List<String> sectionsList = new ArrayList<>();
// ... your json code here
gradeList.add(new GradeModel2(grade.getString("grade"), sectionsList));
}

Related

Data from API parsing in for cycle with bad result

I parse data from API (https://statsapi.web.nhl.com/api/v1/standings) in for cycle. In debug mode, I see, that data are correct from API, but when I write first record to "tabulkaTimov", and for cycle have j=1 (j=2,j=3, ... etc), my first record is replace by next team.
Screenshot of my app:
https://ctrlv.cz/shots/2019/01/03/bbEf.png
It is table of NHL league.
public static List<TableTeamsModel> convertJsonToTableTeams(JsonObject data){
List<TableTeamsModel> tabulkaTimov = new ArrayList<>();
JsonArray pocetDivizii = data.get("records").getAsJsonArray();
for(int i=0;i<pocetDivizii.size();i++){
TableTeamsModel tabulka = new TableTeamsModel();
JsonObject division = pocetDivizii.get(i).getAsJsonObject();
tabulka.setDivisionName(division.get("division").getAsJsonObject().get("name").getAsString());
JsonArray teams = division.get("teamRecords").getAsJsonArray();
for(int j=0;j<teams.size();j++) {
JsonObject teamRecords = teams.get(j).getAsJsonObject();
tabulka.setTeamName(teamRecords.get("team").getAsJsonObject().get("name").getAsString());
tabulka.setGoalsGot(teamRecords.get("goalsAgainst").getAsInt());
tabulka.setGoalsScored(teamRecords.get("goalsScored").getAsInt());
tabulka.setPoints(teamRecords.get("points").getAsInt());
tabulka.setGamesPlayed(teamRecords.get("gamesPlayed").getAsInt());
tabulkaTimov.add(tabulka);
}
}
return tabulkaTimov;
}
Looks like you are creating a new tabulka object outside of your for loop and then add it multiple times in the same arraylist.
This will add it once (reference) and just update its content.
Here is what you can do
public static List<TableTeamsModel> convertJsonToTableTeams(JsonObject data){
List<TableTeamsModel> tabulkaTimov = new ArrayList<>();
JsonArray pocetDivizii = data.get("records").getAsJsonArray();
for(int i=0;i<pocetDivizii.size();i++){
// Remove the creation of the tabulka object from here
JsonObject division = pocetDivizii.get(i).getAsJsonObject()
JsonArray teams = division.get("teamRecords").getAsJsonArray();
for(int j=0;j<teams.size();j++) {
JsonObject teamRecords = teams.get(j).getAsJsonObject();
// And then put the object creation here.
// as we did't have it above, the division name has to be set here too.
TableTeamsModel tabulka = new TableTeamsModel();
tabulka.setDivisionName(division.get("name").getAsString());
tabulka.setTeamName(teamRecords.get("team").getAsJsonObject().get("name").getAsString());
tabulka.setGoalsGot(teamRecords.get("goalsAgainst").getAsInt());
tabulka.setGoalsScored(teamRecords.get("goalsScored").getAsInt());
tabulka.setPoints(teamRecords.get("points").getAsInt());
tabulka.setGamesPlayed(teamRecords.get("gamesPlayed").getAsInt());
tabulkaTimov.add(tabulka);
}
}
return tabulkaTimov;
}
This way you will add a different/new object each time you go over the loop into your ArrayList; - instead of adding the same reference of the same object every time with its data updated.

Split strings on string array

i have String Array like this:
String[] q1={"AAA-BBB","AAA-CCC","AAA-DDD"}
and i want result like this
temp={"BBB","CCC","DDD"}
i tried below code but the result is wrong
for(int i=0;i<q1.length;i++){
ArrayList<String> temp=new ArrayList<>(Arrays.asList(q1[i].split("AAA-")));
}
Try like this:
ArrayList<String> temp=new ArrayList<>();
for(int i=0;i<q1.length;i++){
String[] array = q1[i].split("-");
temp.add(array[1]);
}
You could use substring:
ArrayList<String> temp = new ArrayList<>();
for(int i=0; i<q1.length; i++){
temp.add(q[i].substring(q[i].indexOf('-') + 1, q[i].length()))
}
you find error Because you use split
Splits this string around matches of the given regular expression.
https://docs.oracle.com/javase/7/docs/api/java/lang/String.html
q1[i].split("AAA-")
in this line you got 2 result splited 0 = "" AND 1 = "BBB"
so you need to pick the sec result
you have multi Solution
like https://stackoverflow.com/a/50234408/6998825 said
String[] array = q1[i].split("-");
temp.add(array[1]);
//change this q1[i].split("AAA-") to
q1[0].substring(4)
if your AAA- is not going to change
Have you tried creating the ArrayList outside of the loop? As previously you were creating a new ArrayList for every element in your string array
ArrayList<String> temp = new ArrayList<>();
for(int i=0;i<q1.length;i++){
temp.add(q1[i].substring(4);
}
Assuming that "AAA-" is not going to change.

Removing Key String from JSON Array when converting to List

I am rather new to JSON at the moment, but I need to convert a JSON response that contains the same key, but different values to an ArrayList to use it with my spinner.
I tried it like here: Converting JSONarray to ArrayList
But i get the whole json string, but just need the value part.
I can't figure out how to do this and found no answer that worked for me :/
What I want would be a List like:
City1
City2
City3
But i have in my spinner:
{"city":"name1"}
{"city":"name2"}
{"city":"name3"}
Code I have is:
JSONArray obj = new JSONArray(response);
Spinner availableCitySpin;
availableCitySpin = (Spinner) findViewById(R.id.avCitySp);
List<String> cityValues = new ArrayList<String>();
if (jarr != null) {
for (int i=0;i< jarr.length();i++){
cityValues.add(jarr.getString(i).toString());
}
}
ArrayAdapter<String> cityAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, cityValues);
cityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
availableCitySpin.setAdapter(cityAdapter);
availableCitySpin.setSelection(0);
Change your code to something like this:
...
for (int i=0;i< jarr.length();i++){
JSONObject cityObject = jarr.getJSONObject(i);
cityValues.add(cityObject.getString("city"));
}
...
Try this:
First use split
For example: String[] result = splits[0].split(":");
you will get two item in array result. result[0]= {"city" and result[1] = "name1"}
If you want to get the key use result[0]
remove sign from result[0] using replace. Example: data = result[0].replace("\"","").replace("{","");
use it in loop, should work

Two separate ASyncTasks wrongly combining data when processing JSON

I have a project with a TabLayout + ViewPager to scroll through two different fragments (one shows data happening currently and the other shows all data).
In the onCreateView's of both of these I call the same ASyncTask class with the only difference being the params changing.
FetchItems asyncTask = new FetchItems(getContext(), this);
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"someParams");
The JSON result is then processed here:
try {
LinkedList<LeagueItem> leagues = new LinkedList<>();
LeagueItem newLeague;
//For every league in the array
for (int i = 0; i < jsonBody.length(); i++) {
newLeague = new LeagueItem();
//Hold the league games
JSONObject jsonLeagueInfo = jsonBody.getJSONObject(i);
newLeague.setLeagueName(jsonLeagueInfo.getString("name"));
JSONArray leagueMatches = jsonLeagueInfo.getJSONArray("matches");
//For every match in that league
for(int j = 0;j<leagueMatches.length();j++){
JSONObject matchInformation = leagueMatches.getJSONObject(j);
JSONArray teamsArray = matchInformation.getJSONArray("teams");
MatchItem currentMatch = new MatchItem();
//For both teams in the match
for(int k=0;k<2;k++){
JSONObject teamInfo = teamsArray.getJSONObject(k);
String name = teamInfo.getString("name");
String logoUrl = teamInfo.getString("logo");
JSONObject scores = teamInfo.getJSONObject("results");
String runningScore = scores.getString("runningscore");
TeamItem currentTeam = new TeamItem(shortName, logoUrl, Integer.parseInt(runningScore), homeNum);
currentMatch.addTeam(currentTeam);
}
newLeague.addMatch(currentMatch);
}
leagues.add(newLeague);
}
return leagues;
}
I'm finding that both objects returned have crossover data which shouldn't be there. Both of the parent objects are correct in that they add the correct number of league items, however every league contains pretty much all the data that I'm iterating over. Am I missing something huge here? I thought that by calling executeOnExecuter I would be getting two completely separate threads with different objects.
Thanks.

Using GSon how to get multiple vaues from JSONObject

Hi the below is my response from format
object {6}
csdfgi_fgid : 4casdff9743a1-3f9asdf2-4
fesdfgedVsdfgersionsfdg : 7
sdfg : 28
feesdfgdStart : 0
fesdfedCsdfgoudfsgnt : 28
discover[28]
0{4}
DiscCat : Tip
templateCat{2}
name : tip.tp
version : 2
timestamp : 1421146871251
content{1}
I am getting these values using Serializable in class like below
#SerializedName("csdfgi_fgid")
public String sCdfsisdfId;
#SerializedName("feedVersion")
public Long lFesdfgedVsdfgfsersdfsion;
#SerializedName("feed")
public ArrayList<DiscoverModel> discover;
Now in the array list again there is a Json Object "templateCat" which has two parameters "name , version". Now how to get values from this JSON Object
First of all you need to assign all the JSONObject that you are getting in a POJO class. After that getting JSONObject(templateCat) from JSONArray(discover) you have to do looping. For example:
for(int i=0;i<discover.size();i++){
TemplateCat templateCat = discover.get(i).getTemplateCat();
String strName = templateCat.getName();
String strVersion = templateCat.getVersion();
//If you want to get all name and version as list. Add strName and strVersion to ArrayList. <br>
For Example : nameArray.add(strName);
versionArray.add(strVersion);
}
You'll have to get that JSON array first, iterate thru it and then use Gson to convert it into your desired object.
JSONObject rootJson = /* Get your JSON object here */;
JSONArray nestedArray = rootJson.getJsonArray("your_nested_json_array_name");
List<YourObject> objects;
for(int i = 0; i < nestedArray.size(); i++) {
String objectJsonString = nestedArray.get(i);
YourObject o = new Gson().fromJson(objectJsonString, YourObject.class);
objects.add(o);
}
..the last thing you'd need to do is to set our objects list to your desired instance.

Categories

Resources