我有一个街道的城市地图,我需要(取消)序列化。每条街道都由City和id标识,如下所示:
private final City city;
private final long id;
该城市包含该城市所有街道的列表(City.streetList
),因此在保存模型时我可以执行类似
serializeToFile(modelFile, currentCity);
这有效并且没有问题,但现在我想通过网络发送街道(也使用序列化)。当我对街道进行序列化时,显然城市对象也会被序列化,因此所有街道都会被序列化,从而导致非常大的数据包大小。显然。
我不能让city
瞬态,因为需要唯一识别街道。我也不能让City.streetList
瞬态,因为我需要我的模型列表。
每个城市都有一个唯一的ID,所以这样的事情应该是可能的
private void writeObject(ObjectOutputStream out) throws IOException {
if (serializeForNetwork) { // How can I know this here?
out.writeObject(city.getId());
} else {
out.writeObject(city);
}
out.write(id);
}
如上所述,我不知道对象应该如何知道它被写入网络(在序列化之前调用street.setWritingToNetwork(true)
似乎不仅仅是丑陋)并且这可能不是一个好的解决方案吗?
非常感谢任何想法! : - )
答案 0 :(得分:2)
如果您无法知道对象被序列化为文件或网络,您应该始终写出城市ID而不是整个城市。有一个方法可以通过ID来查找城市。
另一种使用方法是序列化代理。在此pdf中查看有关它的详细信息:Effective Java Reloaded。基本上,序列化代理与使用对象的逻辑状态序列化的对象完全不同。该对象重写writeReplace和readResolve方法以编写代理而不是此对象,并通过读取代理创建对象。代理人也只会写城市ID,而不是整个城市。
答案 1 :(得分:2)
一种解决方法可能是重新设计您的应用程序,以便您的Street对象不再包含对城市的引用,而只包含“城市ID”。城市对象可以转到单独的哈希映射:
private final long cityId;
private final long id;
和某处的转换器:
public static City getCity(long id) {
return cityMap.get(id);
}
序列化街道对象将变得非常小,您只需序列化并存储或发送citymap
一次。