Open bremerjonathan opened 8 years ago
Been away for some time. Will do it!
How to use GSON to serialize(deserialize) jctree? Thanks in advance.
Most of the tree implementations have a default constructor, so they should work with GSON. KAryTree doesn't have one so that may present some problems. Did you see any specific error message when you tried to (de)serialize trees?
My code like below:
public class GsonExample { private static final String TAG = "GsonExample"; private GsonExample() { //no instance }
public static void testJCTree() {
final ArrayListTree<Shape> tree = new ArrayListTree<>();
try {
Circle circle = new Circle();
circle.radius = 5;
circle.x = 5;
circle.y = 5;
tree.add(circle);
Rectangle rectangle = new Rectangle();
rectangle.x = 7;
rectangle.y = 7;
rectangle.width = 7;
rectangle.height = 7;
tree.add(circle, rectangle);
Diamond diamond = new Diamond();
diamond.x = 9;
diamond.y = 9;
diamond.width = 9;
diamond.height = 9;
tree.add(circle, diamond);
dump(tree); //----------- output 0
final TypeToken<ArrayListTree<Shape>> token = new TypeToken<ArrayListTree<Shape>>() {};
RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory =
RuntimeTypeAdapterFactory.of(Shape.class, "type")
.registerSubtype(Rectangle.class, "Rectangle")
.registerSubtype(Circle.class, "Circle")
.registerSubtype(Diamond.class, "Diamond");
final GsonBuilder builder = new GsonBuilder().registerTypeAdapterFactory(shapeAdapterFactory);
final Gson gson = builder.create();
final String jsonStr = gson.toJson(tree, token.getType());
Log.d(TAG, "testJCTree: jsonStr = " + jsonStr); //--------------------output 1
final ArrayListTree<Shape> retree = gson.fromJson(jsonStr, token.getType());
dump(retree);//----------- output 2
} catch (NodeNotFoundException e) {
e.printStackTrace();
}
}
private static void dump(final ArrayListTree<Shape> tree) {
final HashSet<Shape> seen = new HashSet<>();
dump(tree, tree.root(), "", seen);
}
private static void dump(final ArrayListTree<Shape> tree, Shape shape, String indent, final HashSet<Shape> seen) {
if (!seen.add(shape)) {
Log.w(TAG, "dump: repeat add");
return;
}
Log.d(TAG, indent + shape);
indent += " ";
try {
List<Shape> children = tree.children(shape);
for (int i = 0; i < children.size(); i++) {
final Shape child = children.get(i);
dump(tree, child, indent, seen);
}
} catch (NodeNotFoundException e) {
e.printStackTrace();
Log.e(TAG, "dump: exception:" + e.getMessage());
}
}
abstract public static class Shape {
int x;
int y;
}
public static class Circle extends Shape {
int radius;
@Override
public String toString() {
return "Circle{x = " + x + ", y = " + y + ", radius = " + radius + "}";
}
}
public static class Rectangle extends Shape {
int width;
int height;
@Override
public String toString() {
return "Rectangle{x = " + x + ", y = " + y + ", height = " + height + ", width=" + width + "}";
}
}
public static class Diamond extends Shape {
int width;
int height;
@Override
public String toString() {
return "Diamond{x = " + x + ", y = " + y + ", height = " + height + ", width=" + width + "}";
}
}
}
output 0: the root is Circle, the first child of root is Rectangle, the second child is Diamond Circle{x = 5, y = 5, radius = 5} Rectangle{x = 7, y = 7, height = 7, width=7} Diamond{x = 9, y = 9, height = 9, width=9}_
output 1: strange, some fields in ArrayListTree are missing! testJCTree: jsonStr = [{"type":"Rectangle","height":7,"width":7,"x":7,"y":7},{"type":"Circle","radius":5,"x":5,"y":5},{"type":"Diamond","height":9,"width":9,"x":9,"y":9}]
output 2:the root is Rectangle,WRONG! Rectangle{x = 7, y = 7, height = 7, width=7} Circle{x = 5, y = 5, radius = 5} Diamond{x = 9, y = 9, height = 9, width=9}
Thanks!
Could you have your classes implement Serializable please?