xStream深度嵌套。延迟初始化

时间:2015-04-27 14:10:57

标签: java nested xstream self-reference

想象一下代表Vagon的下面的课程:

    class Vagon {
            int id;
            Vagon nextVagon;
    }

它只有两个字段:id和对下一个类实例的引用。 所以,想象一下我们有代表火车的这个对象的列表(第一个构造函数arg是id,第二个 - next Vagon ref):

            Vagon vagon5 = new Vagon( 5, null );
            Vagon vagon4 = new Vagon( 4, vagon5 );
            Vagon vagon3 = new Vagon( 3, vagon4 );
            Vagon vagon2 = new Vagon( 2, vagon3 );
            Vagon vagon1 = new Vagon( 1, vagon2 );
            Vagon vagon0 = new Vagon( 0, vagon1 );

vagon0 - 是最后一个,旁边是vagon1,依此类推。 因此,当我使用xstream序列化这个阴道的列表时,我得到了这样的smth:

        <list>
          <TrainTest_-Vagon>
            <id>0</id>
            <nextVagon>
              <id>1</id>
              <nextVagon>
                <id>2</id>
                <nextVagon>
                  <id>3</id>
                  <nextVagon>
                    <id>4</id>
                    <nextVagon>
                      <id>5</id>
                    </nextVagon>
                  </nextVagon>
                </nextVagon>
              </nextVagon>
            </nextVagon>
          </TrainTest_-Vagon>
          <TrainTest_-Vagon reference="../TrainTest_-Vagon/nextVagon"/>
          <TrainTest_-Vagon reference="../TrainTest_-Vagon/nextVagon/nextVagon"/>
          <TrainTest_-Vagon reference="../TrainTest_-Vagon/nextVagon/nextVagon/nextVagon"/>
          <TrainTest_-Vagon reference="../TrainTest_-Vagon/nextVagon/nextVagon/nextVagon/nextVagon"/>
          <TrainTest_-Vagon reference="../TrainTest_-Vagon/nextVagon/nextVagon/nextVagon/nextVagon/nextVagon"/>
        </list>
事实上 - 我有第一个大vagon0,其中包括所有其他的阴道,其他列表成员 - 是参考。

问题是 1)如果列表大小非常大xStream由于堆栈限制而无法序列化 - 我只是得到StackOverflow错误。 2)输出很难读:我想要那样的东西:

                <list>
                  <TrainTest_-Vagon>
                    <id>0</id>
                    <nextVagon reference="..ref to vagon1..">
                  </TrainTest_-Vagon>
                  <TrainTest_-Vagon>
                    <id>1</id>
                    <nextVagon reference="..ref to vagon2..">
                  </TrainTest_-Vagon>
                  <TrainTest_-Vagon>
                    <id>2</id>
                    <nextVagon reference="..ref to vagon3..">
                  </TrainTest_-Vagon>
                  <TrainTest_-Vagon>
                    <id>3</id>
                    <nextVagon reference="..ref to vagon4..">
                  </TrainTest_-Vagon>
                  <TrainTest_-Vagon>
                    <id>4</id>
                    <nextVagon reference="..ref to vagon5..">
                  </TrainTest_-Vagon>
                  <TrainTest_-Vagon>
                    <id>5</id>
                    <nextVagon reference="..null..">
                  </TrainTest_-Vagon>
                </list>

所以,从科技的角度来看,我认为我们说的是懒惰的编组 - 第一个法术阴道留下了“nextVagon”的空白 - 然后当我们将所有列车记忆插入引用时。 有没有办法在xStream中执行此操作,或者我必须将自己的Converter编写为TrainList?

编辑:在现实生活中,Vagon课程也可以有成员参考以前的Vagon,甚至可以连接到它的阴道列表,所以没有我们可以解决这个问题只是改变列表顺序(序列化顺序) - 我们应该假设每个阴道都引用另一个。

2 个答案:

答案 0 :(得分:0)

如果看起来可行,请考虑在序列化之前恢复列表 - 这将使xstream呈现类似于您期望的XML。

答案 1 :(得分:0)

执行此操作的唯一方法是使用您自己的Converter。 XStream没有任何内置的惰性编组机制。

关于转换为列表:如果Vagons可以引用前一个和下一个Vagons,则并不总是可以对它们进行排序,以便您已经编组了前一个/下一个引用。如果您还没有编组引用,那么XStream将在适当的位置编组它,您仍将获得嵌套布局。

如果您真的不想制作转换器,可能会有解决方法:

  • 听起来你的Vagons可能是一个Tree结构。如果您删除previousVagon引用,则可以将它们从向上的列表中排序。
  • 您可以使用omitField来阻止XStream序列化上一个/下一个引用,但是您必须单独存储引用(例如地图)并在解组后修复它们。此外,参考文献不会在Vagon列表中显示,因为它们被省略了。你会得到类似的东西:

    <VagonHolder>
      <vagonList>
        <Vagon>
          <id>1</id>
        </Vagon>
        <Vagon>
          <id>2</id>
        </Vagon>
        <Vagon>
          <id>3</id>
        </Vagon>
      </vagonList>
      <nextVagonsMap>
        <entry>
          <Vagon reference="../../../vagonList/Vagon"/>
          <Vagon reference="../../../vagonList/Vagon[2]"/>
        </entry>
        <entry>
          <Vagon reference="../../../vagonList/Vagon[2]"/>
          <Vagon reference="../../../vagonList/Vagon[3]"/>
        </entry>
      </nextVagonsMap>
    </VagonHolder>