简体   繁体   中英

How to properly serialize and deserialize an array of objects into/from json?

I'm trying to implement a friends list which needs to be stored in a .json file, in Kotlin/Java with libgdx, but this isn't neccesary(Java is fine). My code for (1) doesn't work so instead of pasteing it here I'll just try to explain my design and only paste the one for (2) as this I believe is closer to a good implementation.

  1. I made a "Friend" class. When adding a new friend the main thread created such an object, then I read the existing "FriendsList.json" into a string, edited the string by removing "]" and appending the serialized Friend object and a "]" to close the array. I had and still have a feeling this isn't good, so I changed it.
  2. I made a "FriendArray" class, in which I thought of storing "Friend" objects in an List. I think this would allow me to get rid of the string manipulation code, and just serialize the FriendList class itself, which would hopefully also be easier to read. One of the problems is that addFriendToListOfFriends() doesn't add the data in the objects (it adds "{}" instead of also inserting the name and id).

What do you think of (2) ? Do you know a better way of doing this?

(Just to be clear, I'm more interested in the design and less about compilable code)

import com.badlogic.gdx.files.FileHandle
import com.unciv.json.json (this is com.badlogic.gdx.utils.Json)
import java.io.Serializable

class FriendList() {
    private val friendsListFileName = "FriendsList.json"
    private val friendsListFileHandle = FileHandle(friendsListFileName)
    private var friendListString = ""

    var arrayOfFriends = FriendArray()

    fun getFriendsListAsString(): String {
        return friendsListFileHandle.readString()
    }

    fun addNewFriend(friendName: String, playerID: String) {
        val friend = Friend(friendName, playerID)
        arrayOfFriends.addFriendToListOfFriends(friendName, playerID)
        saveFriendsList()
    }

    fun saveFriendsList(){
        friendListString = getFriendsListAsString()

        friendListString = friendListString.plus(json().prettyPrint(arrayOfFriends))

        friendsListFileHandle.writeString(friendListString, false)
    }
}

class Friend(val name: String, val userId: String)

class FriendArray(): Serializable {
    var nrOfFriends = 0

    var listOfFriends = listOf<Friend>()

    fun addFriendToListOfFriends(friendName: String, playerID: String) {
        var friend = Friend(friendName, playerID)
        listOfFriends.plus(friend)
    }
}

You don't realy need a class FriendArray for this. You can just searialize a list to JSON. Also it's easier to load the existing friend list to a list, add the new friend to the list and serialize the new list, instead of appending a string.
This way you won't have to worry about the correct JSON format or string manipulation. You just add an object to a list, and serialize the list.

Something like this should work (in java, sorry I don't know enough kotlin to implement this):

public void addFriendAndSerializeToFile(Friend friend) {
    // load existing friend list from the file
    Json json = new Json();
    // here the first parameter is the List (or Collection) type and the second parameter is the type of the objects that are stored in the list
    List<Friend> friendList = json.fromJson(List.class, Friend.class, friendsListFileHandle);
    
    // add the new friend to the deserialized list
    friendList.add(friend);

    // serialize the whole new list to the file
    String serializedFriendListWithNewFriendAdded = json.prettyPrint(friendList);
    
    // write to the file handle
    fileHandle.writeString(serializedFriendListWithNewFriendAdded, false);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM