2

我有一个四叉树*,我想在多台不同的机器上使用它。调用构造函数(即构建树)需要很长时间。我不想每次需要使用它时都构建树。

我正在寻找一种方法将我的树保存在硬盘中,将其发送到每个节点,然后快速将其加载到内存中,以便我可以执行查找。

序列化可以帮助我吗?我知道我可以序列化树,将其保存到磁盘然后反序列化(这就是我所知道的关于序列化的全部内容)。据我所知,反序列化步骤需要一个默认构造函数来构建树。由于构建树的计算成本很高,所以这对我没有用。

有什么方法可以导入持久树而不必每次都重建它?

*我使用的四叉树基础代码:https ://bitbucket.org/utcompling/textgrounder/src/f38150c7f33a/src/main/java/ags/utils/KdTree.java

抱歉,如果这太基本了,它与以下内容密切相关:https ://stackoverflow.com/questions/14701245/how-do-i-perform-kd-tree-lookups-in-hadoop

编辑:所以,看起来最少继承类的无参数构造函数是将被调用的构造函数。这是我的雇佣关系:

抽象的KDTree

QuadTree 扩展 KdTree

SpecialQuadTree(有一个 QuadTree 实例)

现在,当我使所有内容都可序列化时,我只能序列化 SpecialQuadTree(否则我得到 NotSerizable 或 InvalidClassException 没有有效的构造函数):

抽象 KDTree 实现 Serializable

QuadTree 扩展 KdTree 实现 Serializable

SpecialQuadTree 实现 Serializable (有一个 QuadTree 的实例)

所以,我想我可以将 Serializable 从 KdTree 中取出,然后给它一个不做任何事情的无参数构造函数?这不容易,我没有写,也不懂KdTree类。我想我可以对它进行子类化,给子类一个不做任何事情的无参数构造函数,并从中继承 QuadTree ...

编辑:好的,我有一个抽象类抽象KDTree实现可序列化

并由此扩展:QuadTree extends KdTree implements Serializable

从我所有的实验中,我需要在两者上实现 Serializable。现在,

public QuadTree() {
    super(2, 1000000);
    System.out.println("QuadTree no-args!");
}

protected KdTree(int dimensions, Integer sizeLimit) {
    System.out.println("KdTree, constructor!");

因为我从来没有看到它打印出来(除了最初的构造......),我想这一切都很好。

4

3 回答 3

3

当一个对象在 Java 中反序列化时,只会调用一些无参数的构造函数(参见这篇文章)。

最简单的方法是制作所有涉及的类Serializable。那么你的任何构造函数都不会被调用。如果您不能这样做,请确保您的Serializable可以访问第一个 non-Serializable 类的无参数构造函数

如果是您控制的非Serializable基类,您可以将昂贵的逻辑移动到不同的构造函数(比如说,使用一个虚拟boolean参数)并提供一个简单的无参数构造函数,它什么都不做。然后在反序列化后,您的所有字段都将在那里,而没有计算开销。

信息的最终来源是序列化规范

于 2013-02-12T20:58:48.007 回答
2

据我所知,反序列化步骤需要一个默认构造函数来构建树

如果您正在考虑 Java 对象序列化,则不会。

看起来继承最少的类的无参数构造函数将被调用。

不会。调用最近的不可序列化基类的无参数构造函数。

我想我可以将 Serializable 从 KdTree 中取出,然后给它一个无所事事的无参数构造函数?

为什么?别管它。

于 2013-02-12T20:56:54.957 回答
0

如果您使用的是 Jackson,那么拥有一个自定义反序列化器并附加到您尝试反序列化的类怎么样?

于 2014-11-24T19:15:51.060 回答