Tutorial How to serialize classes and collections

Discussion in 'Resources' started by Zombie_Striker, Mar 21, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    Zombie_Striker

    Although this is more of a Java tutorial, this thread covers how to serialize classes and objects.

    What does it mean to serialize an object:

    Serializing objects mean to convert an object into bytes or a string. By turning the object into a string or bytes, you can save the object to a file, allow you to load those objects after server reloads. Most of bukkits objects can be serialized, which is why you can save them to configs. That is why you still have an inventory and blocks are in the same spot after you restart your server.

    How do you serialize an object:

    All you need to do is put all the data for a specific class into a single string. For the purpose of this tutorial, let me use the following class:
    Code:
    public class ExampleClass{
    
    private int number = -1;
    private String message = "Test";
    private List<String> collection = new ArrayList<String>();
    }
    The main goal is to take those three objects and convert them into one string. To do that, we will override the classes 'toString' method which gets called whenever the object needs to be turned into a string.
    Code:
    @Override
    public String toString(){
    
    }
    Before we continue serializing the object, we need to think a head as to how we will determine the ends of each value. Since all three values will be in one string, we need to develop a way of separating each value. In this example, I will recommend using the character sequence "&SPLIT&" to show the ends of each value.
    To make it easier to modify if needed, I will create a field to store this sequence.
    Code:
    private String split = "&SPLIT&";
    @Override
    public String toString(){
    
    }
    Now that have the sequence we will split the string at, we need to add all the values. Adding 'number' and 'message' to the string is easy since they are only single values. Because of this, I will add show you how you would add those first.
    Code:
    private String SPLIT = "&SPLIT&";
    @Override
    public String toString(){
    String serializedString = number+SPLIT+message;
    }
    As you can see above, we have the split string in the middle the number and this message. All you would need to do to get those two values would be to split the string at that sequence, but that is for a latter step.

    The List is trickier because it stores multiple values. To store the List, you will need to first to store how many values there are in the List, and then add all the values. In the following example, we will first get how many objects are in the list, and then loop through them and add them to the string. After that, we can return the string.
    Code:
    private String SPLIT = "&SPLIT&";
    @Override
    public String toString(){
    String serializedString = number+SPLIT+message;
    
    int size = collection.size();
    
    //Here we are adding the size to the string.
    serializedString += SPLIT+size;
    
      //For this example, we are looping through strings. If this was a custom class or another object,
      //you would need to have a toString method to convert that object to a string.
    for(String string : collection){
       serializedString += SPLIT+string;
    }
    return serializedString;
    }

    How do you de-serialize an object:

    Now that we have serialized the string, we need to be able to de-serialze it and convert it back into an object. To do this, we will create a static method that will return the class instance. Using the same example as above, this is how we would create it:
    Code:
    public static Example deserialize(String serializedString){
    
    }
    The first thing we need to do is split the string at the sequence we decided apon at the top of this thread. To split a string, we use the .split() method which returns a string array. It should look like the following:
    Code:
    public static Example deserialize(String serializedString){
    String[] values = serializedString.split(SPLIT);
    }
    Now that we split the string, we have to assign all the values that were in this string. Although you can directly assign each value when you set the object, in this example, we will create some variables first.
    Code:
    public static Example deserialize(String serializedString){
    String[] values = serializedString.split(SPLIT);
    
    //The first variable is the 'number' field, so the first object in the 'values' array will be that number
    int number = Integer.valueOf(values[0]);
    //The second variable is the 'message' field, so the second object in the 'values' array will be  that message
    String message = values[1];
    //The third variable is the size of the list field, so the third object in the 'values' array will be the size
    int size = Integer.valueOf(values[2]);
    
    List<String> collection = new ArrayList<String>();
    
    //Now we need to loop through the rest of the values in the array. This will start at the third  index, and loop through all the rest of the values.
    for(int i = 3; i < 3+size; i++){
      collection.add(values[i]);
    }
    
    }
    After this, all you need to do is create the 'Example' instance and set it's values. Since setting fields and variables is basic Java knowledge, I will not cover that here and move onto saving thing the serialized string and loading the objects.

    Saving and loading serialized Strings.
    Saving serialized strings is exactly the same as saving regular strings. Just save the string to your config, and when you wish to load the object from the file, use the following line:
    Code:
    Example exampleObject = Example.deserialize(serializedString);
    That will be the end for this tutorial. If I have made any mistakes, or if I have not explained any section clearly, please comment below what I should add.
     
    Last edited: Mar 22, 2016
    Gonmarte likes this.
  2. Offline

    mcdorli

    Why not override the toString method in the main class too?
     
  3. Offline

    I Al Istannen

    @Zombie_Striker
    Is there any particular reason not to use the Config API with ConfigurationSerializable? I have seen everybody saving to Strings (granted about 3 people, statistically totally valuable) and nobody seemed to use the config.
     
  4. Offline

    Zombie_Striker

    @mcdorli
    That would would be better. Editing that part of the tutorial

    @I Al Istannen
    From my experience with using it, objects would normally get corrupted or would no be saved at all. If I could guarantee that any data stored using it would not be corrupted or lost, then I would recommend using it.
     
    mcdorli likes this.
  5. Offline

    I Al Istannen

    @Zombie_Striker
    Oh ok. I have used it in every plugin I made and so far it seemed to be reliable. Will keep an eye on it.

    Thanks :)
     
  6. Offline

    Gonmarte

    @Zombie_Striker Why the method deserialize doesnt have a return statement?
     
  7. Offline

    Zombie_Striker

    @Gonmarte
    Because although this is a tutorial, I do not want people to copy and paste the methods.
     
  8. Offline

    Gonmarte

    Sorry, I didnt know that :p
     
Thread Status:
Not open for further replies.

Share This Page