AtomicInteger увеличивает при использовании unmarshaller JAXB на сложный класс - PullRequest
0 голосов
/ 11 июня 2018

У меня проблема с AtomicInteger при использовании unmarshaller JAXB.У меня есть следующий пример кода, который я пытаюсь демонтировать MyTree из XML-файла.Я создаю уникальный идентификатор для каждой вершины, используя AtomicInteger.При отмене вызова MyTree он увеличивается при создании краев.Если у меня есть три вершины в vertexList и два ребра в edgeList в myTree.xml, после демаршаллинга nextID для создания новой вершины создаст 8 вместо 4. Так как для каждого ребра он добавляет вершину для sourceVertex и targetVertex.Не могли бы вы помочь мне понять, что я делаю не так?и как я могу преодолеть эту проблему.Большое спасибо.(Я действительно новичок в JAVA и JAXB) * ​​1001 *

JAXBContext context= JAXBContext.newInstance(MyTree.class);
Unmarshaller unmarshaller= context.createUnmarshaller();
MyTree newTree= (MyTree) unmarshaller.unmarshal(new File("MyTree.xml"));


@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class MyTree{

   ArrayList<Vertex> vertexList =new ArrayList<Vertex>();
   ArrayList<Edge> edgeList = new ArrayList<Edge>();

   public MyTree() {

   }
   ...
}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class Vertex{

  public int vertexId;
  private static AtomicInteger nextId = new AtomicInteger(0);
  public Vertex() {
    this.vertexId=nextId.incrementAndGet();     
  }
  ...
}

 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlRootElement
 public class Edge {

    private Vertex sourceVertex;
    private Vertex targetVertex;
    private EdgeType edgeType;

    public Edge () {

    }
    ... 
 }
   enum EdgeType 
   {
     White,
     Red, 
     Blue;
   }

1 Ответ

0 голосов
/ 11 июня 2018

Трудно сказать из кода, который вы дали, каким было бы на самом деле лучшее решение, но вы могли бы сделать что-то вроде этого:

Из того, что я могу сказать, есть два способа создать Vertexс помощью конструктора или десериализации, последняя создает проблему, вызывая конструктор слишком часто.Поэтому удалите управление идентификаторами для дополнительного класса и запрашивайте идентификатор только тогда, когда вы уверены, что он вам нужен.

Во-первых, вам необходимо рефакторинг кода в конструкторе, не увеличивая счетчик.Итак,

@XmlRootElement
class Vertex {
    private int vertexId;
    public Vertex() { // initialize without incrementing the counter
    }
}

Переместите управление идентификаторами в отдельный класс.Например,

class VertexManager {
    // Singleton
    private static VertexManager INSTANCE;
    private VertexManager() { }
    public static VertexManager getInstance() {
        if (INSTANCE == null) { INSTANCE = new VertexManager(); }
        return INSTANCE;
    }

    // keep track of the ids
    private AtomicInteger currentId = new AtomicInteger();

    // create new vertex
    public static Vertex create() {
        Vertex created = new Vertex();
        register(created);
        return created;
    }
    // add previously created vertex
    public void register(Vertex v) {
        int id = currentId.incrementAndGet();
        v.setId(id);
    }
}

Теперь весь ваш текущий код опирается на конструктор, увеличивающий его, вы должны убедиться, что во всех этих местах вместо него используется VertexManager#create()!Я предлагаю установить для конструктора Vertex значение private, чтобы спровоцировать ошибки компилятора там, где он используется, а затем сбросить после того, как вы их все изменили.

Метод register, который вы можете использовать для завершения десериализации;после прочтения дерева все Vertex становятся стабильными, но им все равно необходимо назначить свои идентификаторы.Итак

JAXBContext context= JAXBContext.newInstance(MyTree.class);
Unmarshaller unmarshaller= context.createUnmarshaller();
MyTree newTree= (MyTree) unmarshaller.unmarshal(new File("MyTree.xml"));
newTree.getVertices().forEach(v -> VertexManager.getInstance().register(v));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...