【问题标题】:How to serialize a java object which contains object references without serializing the objects referred to?如何序列化包含对象引用的java对象而不序列化引用的对象?
【发布时间】:2015-02-09 10:20:15
【问题描述】:

我正在 java 中实现 B Plus Tree。我有一个节点类,我在其中维护对子对象 Nodes 的引用。现在,当我序列化任何节点时,它也会序列化所有子节点。我想要的是仅序列化该节点和对子节点的引用。我尝试将节点对象编写为字节流,但在反序列化时它不起作用。

public class BNode implements Serializable
{
    LinkedList<Float> keys;
    LinkedList<BNode> childPointers;
    BNode parent;
 ...
}

在 B+ 树中,节点保存在磁盘中,我必须模拟该操作。现在每个页面都是 2 KB(比如说),所以在我的每个节点中,我保存了大约 2044 个字节的数据(255 个浮点值和 256 个节点引用 - 总计 255*4 + 255*4 + 一些其他 10 个字节的数据)模拟单个节点的单个文件。现在,如果我序列化父节点,它将整个树序列化为单个文件,从而破坏了整个目的

【问题讨论】:

  • “对子节点的引用”是什么意思?
  • 你的意思是你只需要序列化父母吗?
  • 我需要分别序列化每个节点。我的意思是父节点序列化文件不能同时序列化所有引用节点

标签: java serialization deserialization datainputstream dataoutputstream


【解决方案1】:

您必须使用transient。这会从序列化中排除变量。

public class BNode implements Serializable
{
    LinkedList<Float> keys;
    LinkedList<BNode> childPointers;
    transient BNode parent;
 ...
}

如果您需要更复杂的规则,您可以通过实现此方法来覆盖(反)序列化的默认行为:

private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

查看http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html 了解详细说明。

【讨论】:

  • childPointer 列表怎么样。序列化对象也会序列化 childPointer 列表中的所有节点。
【解决方案2】:

在任何实际的基于磁盘的 B 树中,每个索引块都需要包含与该块中的键对应的块的磁盘偏移量。因此,您需要将参考数组设为瞬态,并为偏移量添加一个非瞬态数组long

如果可以避免的话,我还建议您不要保留父引用或偏移量。如果您记住每个搜索路径,您可以避免它。在大树中,当您拆分内部节点时,您不希望更新 N/2 个子节点中的父链接以及您必须做的所有其他事情。这是一个非常重要的性能打击。

【讨论】:

    猜你喜欢
    • 2011-01-01
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 2015-10-15
    • 2015-08-30
    • 1970-01-01
    相关资源
    最近更新 更多