Burak Burak - 5 months ago 14
JSON Question

Can I serialize an ArrayList without serializing objects which holds?

Some of objects in my code appear in more than one lists/maps. E.G: the object Question myQuestion is in both ArrayList java and ArrayList serialization. And as far as I know, Gson serializes objects in an ArrayList along with the ArrayList itself. To test it, I ran the following code:

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class serTries {
public static void main(String[] args) {
List<Player> players=new ArrayList<>();
List<Player> secondaryPlayer =new ArrayList<>();
for(int i=0;i<3;i++) {
players.add(i, new Player("John " + i));
secondaryPlayer.add(players.get(i));
} //creating 3 Player objects and putting them in 2 different lists.

try {
Gson gson = new Gson();
String ser=gson.toJson(players);
String secondarySer=gson.toJson(secondaryPlayer);
Type ct = new TypeToken<ArrayList<Player>>(){}.getType();
System.out.println("First list:\n" + ser + "\nSecond list:\n" + secondarySer);
}catch( Exception e)
{
e.printStackTrace();
} } }


It produces the following:


First list:

[{"name":"John 0"},{"name":"John 1"},{"name":"John 2"}]

Second list:

[{"name":"John 0"},{"name":"John 1"},{"name":"John 2"}]


and when I create a new list by typing

List<Player> deserializedPlayers = gson.fromJson(ser, ct);
List<Player> deserializedSecondaryPlayers = gson.fromJson(secondarySer, ct);


It creates 6 different objects (3 players from first, and 3 from the second list.)

My question is, is there any way to make it so I can serialize/deserialize a List called onlinePlayers which refers to an instance of "John 1", which also happens to be in List allPlayers, without duplicating "John 1" while still refering to that object?

I'm guessing when I deserialize allPlayers, it will create objects which are different than original ones, so there is no way onlinePlayers can still refer to same object after deserialization. Should I write a custom method to add newly created instance of "John 1" to onlinePlayers after deserialization?

Thank you

Answer

Can I serialize an ArrayList without serializing objects which holds?

Short answer. No.

The point of serialization is that you can reconstruct a copy of the original object from the serialization. If you don't include a serialization of the list elements, then you won't be able to reconstruct the list.

I think you need change the type of the list you are trying to serialize to be a list of names, not a list of players. Alternatively, consider using a database rather than "dumb" serialization.


My question is, is there any way to make it so I can deserialize a List called onlinePlayers which refers to an instance of "John 1", which also happens to be in List allPlayers, without duplicating "John 1" while still refering to that object?

If you were using Java Object Serialization, you could implement a readResolve method on the Player object that looked up the object being deserialized and compared it against a "global" in-memory data structure. (But this is conceptually wrong on a number of levels.)

You could do something similar with a GSON custom deserializer.


However, I thought extracting a data from players list (which holds thousands of objects) each time someone checks online players would be pointless performance wise.

Serialization / deserialization is the wrong solution for this if you have thousands of objects:

  • To update you need to serialize / write the entire list and all objects it contains. Each time. Even if you only made a small change.

  • To read, you need to do most of the work of deserializing, even with your proposed "hack".

  • There is no easy / quick way to do queries against the serialized form.

  • At some point you need to hold the entire deserialized object graph in memory.

You should use a database of some kind.

Comments