简体   繁体   English

在SimpleXML批注中指定集合类型

[英]Specify collection type in SimpleXML annotation

I am using the Simple XML library to serialize a set of elements: 我正在使用简单XML库来序列化一组元素:

@Root(name = "items")
public class Items {

  @ElementList(required = false, inline = true, entry = "item")
  private Set<Item> items;

  public Set<Item> getItems() {
    return items;
  }

  public void setItems(final Set<Item> items) {
    this.items = items;
  }
}

I need the collection to be a Set , but at the same time it needs to be sorted - for this reason, when serializing, I use LinkedHashSet as the actual type of the items . 我需要集合是一个Set ,但同时也需要整理-因为这个原因,序列化的时候,我用LinkedHashSet作为实际类型的items

Set<Item> items = new LinkedHashSet<Item>();
items.add(...);
items.add(...);
items.add(...);
Items root = new Items();
root.setItems(items);
new Persister().write(root, stringWriter);

This works out just fine and the resulting XML contains the Item elements in the correct order. 这样就可以正常工作,并且生成的XML包含正确顺序的Item元素。

The problem is with the deserialization - Simple XML sees that the type is Set , picks an implementation in CollectionFactory.getConversion() : a HashSet , which does not keep the order of the elements. 问题在于反序列化-简单XML看到类型为Set ,在CollectionFactory.getConversion()选择一个实现: HashSet ,它不保留元素的顺序。

One way to fix it is to change the definition of Items : 解决它的一种方法是更改Items的定义:

  @ElementList(required = false, inline = true, entry = "item")
  private LinkedHashSet<Item> items;

  public void setItems(final LinkedHashSet<Item> items) {
    this.items = items;
  }

This works, but it's really against good coding practices. 这行得通,但实际上违反了良好的编码习惯。 Is there a way to tell Simple XML to use LinkedHashSet ? 有没有办法告诉简单XML使用LinkedHashSet

I guess the problem is caused by inlining. 我猜问题是由内联引起的。 If you don't use inline , simple will put all elements as childs into a set-tag. 如果不使用inline ,则simple会将所有元素作为子元素放入set-tag中。 This tag contains eg a class="java.util.LinkedHashSet" attribute, what makes it possible to decide the set-implementation. 该标签包含例如class="java.util.LinkedHashSet"属性,这使得可以确定set-implementation。

But this is impossible for an inline-collection, so simple takes a default one. 但这对于内联集合是不可能的,因此简单地采用默认集合即可。

What you can do: 你可以做什么:

  1. Use private LinkedHashSet<Item> items; 使用private LinkedHashSet<Item> items; as you've already written - this makes very clear what implementation you want 正如您已经写过的-这使您很清楚想要什么实现
  2. Use a constructor where you instantiate the implementation: public Items() { this.items = new LinkedHashSet<>(); } 在实例化实现的地方使用构造函数: public Items() { this.items = new LinkedHashSet<>(); } public Items() { this.items = new LinkedHashSet<>(); }
  3. Write a Converter , where you handle the deserialisation by your own (possible an overkill). 编写一个Converter ,在其中您可以自己处理反序列化(可能会导致过大杀伤力)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM