0

Real title: How do I convert json to custom object using gson(custom object contains ArrayLists and HashMap)?

Problem: I added an HashMap to my custom object and since then when im trying to convert JSON to my custom object I get this error:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 59 path $[0].currentLesson.students.

What do I need to change? ask for any other info you might need from me and I shall give it to you. Thank you!

Code:

private void initializeDatabase() {
        ArrayList<Group> groups = null;

        SharedPreferences sharedPreferences =  getSharedPreferences(Database.SHARED_PREFERENCES_STRING, MODE_PRIVATE);

        Gson gson = new Gson();
        String groupsJason = sharedPreferences.getString(Database.GROUPS_STRING, null);

        Type typeGroup = new TypeToken<ArrayList<Group>>(){}.getType();
        groups = gson.fromJson(groupsJason, typeGroup);

        if(groups == null){
            groups = new ArrayList<>();
        }

        Database.setGroups(groups);
    }

public class Group {

    private String groupName;

    private ArrayList<Student> students;
    private ArrayList<Lesson> lessons;
    private Lesson currentLesson;


    public Group(String groupName) {
        this.groupName = groupName;
        students = new ArrayList<>();
        lessons = new ArrayList<>();
    }

    public Group(String groupName, ArrayList<Student> students) {
        this.groupName = groupName;
        this.students = students;
        lessons = new ArrayList<>();
    }

    public void setCurrentLesson(String currentLesson) {
        this.currentLesson = new Lesson(currentLesson, students);
    }

    public String getGroupName() {
        return groupName;
    }

    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    public ArrayList<Student> getStudents() {
        return students;
    }

    public int getGroupSize() {
        return students.size();
    }

    public Boolean getArrivedToLesson(Student student){
        return currentLesson.getArrivedToLesson(student);
    }

    public Lesson getCurrentLesson() {
        return currentLesson;
    }

    public void saveLesson() {
        lessons.add(currentLesson);
    }

}

public class Lesson {

    private String lessonDate;

    private HashMap<Student, Boolean> students;

    public Lesson(String lessonDate, ArrayList<Student> students) {
        this.lessonDate = lessonDate;
        this.students = new HashMap<>();

        for (Student student : students) {
            this.students.put(student, false);
        }
    }
    
    public String getLessonDate() {
        return lessonDate;
    }

    public void arrivedToLesson(Student student) {
        student.arrivedToLesson();
        students.put(student, true);
    }

    public void didntArriveToLesson(Student student) {
        student.didntArriveToLesson();
        students.put(student, false);
    }

    public Boolean getArrivedToLesson(Student student) {
        return students.get(student);
    }
}

private void saveData(){

        group.saveLesson();

        SharedPreferences sharedPreferences = getSharedPreferences(Database.SHARED_PREFERENCES_STRING, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        Gson gson = new Gson();
        String groupsJason = gson.toJson(Database.getGroups());

        editor.putString(Database.GROUPS_STRING, groupsJason);
        editor.apply();

        Toast.makeText(this, String.format(getResources().getString(R.string.saved_attendance), lessonDate), Toast.LENGTH_SHORT).show();
        onButtonBackClick();
    }
  
  • take a look at https://stackoverflow.com/a/27015959/8527625 – mohammad jalili Aug 28 '20 at 17:28
  • Thank's but, it's not what. I want to save and read ArrayList(my custom object). This object contians HashMap, ArrayList and ArrayList – Elad Kellner Aug 28 '20 at 17:54
  • try printing your JSON string and see what problem you faced with. – mohammad jalili Aug 28 '20 at 20:23
  • How I do that? I'm brand new to json. – Elad Kellner Aug 28 '20 at 20:27
  • Log.d("TAG",groupsJason); – mohammad jalili Aug 28 '20 at 20:28
  • Wait one minute. – Elad Kellner Aug 28 '20 at 20:30
  • D/TAG: [{"currentLesson":{"lessonDate":"28/08/2020","students":{"com.example.attendance_tracker.classes.Student@3944803":true}},"groupName":"check,"lessons":[{"lessonDate":"28/08/2020","students":{"com.example.attendance_tracker.classes.Student@3944803":true}}],"students":[{"lessonsPaid":0,"studentName":"dude1","timesArrivedToLessons":1,"timesDidntArriveToLessons":0}]}] – Elad Kellner Aug 28 '20 at 20:32
  • follow these two links and do like them : https://stackoverflow.com/questions/18544133/parsing-json-array-into-java-util-list-with-gson https://stackoverflow.com/questions/21720759/convert-a-json-string-to-a-hashmap – mohammad jalili Aug 28 '20 at 20:34
  • and here is converting json to hashmap using gson : https://www.baeldung.com/gson-json-to-map – mohammad jalili Aug 28 '20 at 20:35
  • It can't convert alone the json to ArrayList of my custom object? Do I have to get the ArrayLists and map and then set them to the each object and add them to ArrayList? – Elad Kellner Aug 28 '20 at 20:44
  • no I don't think so. did you visit those links carefully? – mohammad jalili Aug 28 '20 at 20:47
  • I saw this comment witch describes my problem: "Expected BEGIN_OBJECT but was BEGIN_ARRAY is happening because HashMap should be HashMap, if the values are always String object you will not have any problems but if the value of some key is diff then String (for example custom object , or list or array) then exception will be thrown . So to be able to parse back everything you need HashMap " My map's key is a custom object so what can I do – Elad Kellner Aug 28 '20 at 21:09

1 Answers1

0

I've managed to solve the problem. The problem was that my map - I changed it to HashMap<String, Object>. The string represents my custom object's main attribute - in my case it's name, the object is a boolean and I casts it when needed.