2015-04-27 2 views
0

Представьте себе следующий класс, представляющий Vagon:xStream глубокая вложенность. Ленивый инициализация

class Vagon { 
      int id; 
      Vagon nextVagon; 
    } 

имеет только два поля: идентификатор и ссылку на следующий экземпляр класса. Итак, представьте, что мы имеем список этих объектов, представляющих поезд (первый конструктор Arg является идентификатор, второй - следующий Вагон исх):

  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 и так на. Так что, когда я сериализация список этого vagons с использованием XStream я получил что-л, как это:

 <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, которая включает в себя все другие vagons и других членов списка - являются refereces ,

Проблемы 1) если размер списка очень большой, xStream не может сериализовать его из-за ограничения стека - я получаю сообщение об ошибке StackOverflow. 2) Выход очень трудно читать: я хотел бы имея smthing так:

   <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> 

Таким образом, с технической точки зрения, я думаю, что мы говорим о ленивых сортировочном - первом Марсало vagons покидающего «nextVagon «blank» - и тогда, когда у нас будет весь поезд в памяти, вставьте рефери. Есть ли способ сделать это в xStream или мне придется написать собственный конвертер в TrainList?

EDIT: В реальной жизни ситуация Вагон класса может иметь член реф к previousVagon, а также, или даже список vagons что может быть подключен к нему, так что нет никакого способа, мы можем решить эту проблему, только изменяя список порядок (сериализация последовательности) - мы должны предположить, что каждый из вагонов имеет ссылку на другую.

ответ

0

Если представляется целесообразным, подумайте о возврате списка перед сериализацией - это приведет к тому, что xstream отобразит XML так, как вы ожидаете.

+0

Он будет работать в этой ситуации, но в реальной жизни каждый вагон не только член nextVagon, но и previousVagon связь - так что нет никакого способа, чтобы найти один без ссылку, чтобы установить его как простой (первый) – user3271133

0

Единственный способ сделать это с вашим собственным Converter. XStream не имеет встроенного ленивого механизма сортировки.

Что касается преобразования в список: если Vagons могут иметь ссылки на предыдущие и следующие Vagons, не всегда можно заказать их так, чтобы вы уже упорядочили предыдущие/следующие ссылки. Если вы еще не определили ссылку, то XStream будет маршалировать ее на месте, и вы все равно получите вложенный макет.

Возможные обходные пути, если вы действительно не хотите, чтобы сделать конвертер:

  • Это звучит как Vagons может быть структура дерева. Если вы удалите ссылки 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> 
    
Смежные вопросы