Java JAXB如何强制解组中的特定顺序

Java JAXB如何强制解组中的特定顺序,java,jaxb,hashcode,unmarshalling,Java,Jaxb,Hashcode,Unmarshalling,我有以下XML: <rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <collection> <link referenceId="id1" foo="foo"/> </collection> <referencable id="id1" name="bar"/> </rootElement> 链接

我有以下XML:

<rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <collection>
        <link referenceId="id1" foo="foo"/>
    </collection>
    <referencable id="id1" name="bar"/>
</rootElement>
链接
最终无法读取,通过调用

Set<Link> links = rootElement.getCollection().getLink();
boolean contains = links.contains(links.iterator().next()); // returns false
收藏:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "collection",
    "referencable"
})
@XmlRootElement(name = "rootElement")
public class RootElement {

    protected Collection collection;
    protected Referencable referencable;
    public Referencable getReferencable() { return referencable; }
    public void setReferencable(Referencable referencable) { this.referencable = referencable; }
    public Collection getCollection() { return collection; }
    public void setCollection(Collection collection) { this.collection = collection; }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Collection", propOrder = {"link"})
public class Collection {

    protected Set<Link> link;
    public Set<Link> getLink() {
        if (link == null) { link = new HashSet<Link>(); }
        return this.link;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Link")
public class Link
{
    @XmlAttribute(name = "referenceId", required = true)
    @XmlIDREF
    @XmlSchemaType(name = "IDREF")
    protected Object referenceId;
    public Object getReferenceId() { return referenceId; }
    public void setReferenceId(Object value) { this.referenceId = value; }

    @XmlAttribute(name = "foo", required = true)
    protected String foo;
    public String getFoo() { return foo; }
    public void setFoo(String foo) { this.foo = foo; }

    @Override public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((foo == null) ? 0 : foo.hashCode());
        result = prime * result + ((referenceId == null) ? 0 : referenceId.hashCode());
        return result;
    }

    @Override public boolean equals(Object obj) {
        if (this == obj) { return true; }
        if (obj == null) { return false; }
        if (getClass() != obj.getClass()) { return false; }
        Link other = (Link) obj;
        if (foo == null) { if (other.foo != null) { return false; } }
        else if (!foo.equals(other.foo)) { return false; }
        if (referenceId == null) { if (other.referenceId != null) { return false; } }
        else if (!referenceId.equals(other.referenceId)) { return false; }
        return true;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Referencable")
public class Referencable
{
    @XmlAttribute(name = "id", required = true)
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlID
    @XmlSchemaType(name = "ID")
    protected String id;
    public String getId() { return id; }
    public void setId(String value) { this.id = value; }

    @XmlAttribute(name = "name")
    protected String name;
    public String getName() { return name; }
    public void setName(String value) { this.name = value; }

    @Override public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override public boolean equals(Object obj) {
        if (this == obj) { return true; }
        if (!super.equals(obj)) { return false; }
        if (getClass() != obj.getClass()) { return false; }
        Referencable other = (Referencable) obj;
        if (name == null) { if (other.name != null) { return false; } }
        else if (!name.equals(other.name)) { return false; }
        return true;
    }
}
可参考:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "collection",
    "referencable"
})
@XmlRootElement(name = "rootElement")
public class RootElement {

    protected Collection collection;
    protected Referencable referencable;
    public Referencable getReferencable() { return referencable; }
    public void setReferencable(Referencable referencable) { this.referencable = referencable; }
    public Collection getCollection() { return collection; }
    public void setCollection(Collection collection) { this.collection = collection; }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Collection", propOrder = {"link"})
public class Collection {

    protected Set<Link> link;
    public Set<Link> getLink() {
        if (link == null) { link = new HashSet<Link>(); }
        return this.link;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Link")
public class Link
{
    @XmlAttribute(name = "referenceId", required = true)
    @XmlIDREF
    @XmlSchemaType(name = "IDREF")
    protected Object referenceId;
    public Object getReferenceId() { return referenceId; }
    public void setReferenceId(Object value) { this.referenceId = value; }

    @XmlAttribute(name = "foo", required = true)
    protected String foo;
    public String getFoo() { return foo; }
    public void setFoo(String foo) { this.foo = foo; }

    @Override public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((foo == null) ? 0 : foo.hashCode());
        result = prime * result + ((referenceId == null) ? 0 : referenceId.hashCode());
        return result;
    }

    @Override public boolean equals(Object obj) {
        if (this == obj) { return true; }
        if (obj == null) { return false; }
        if (getClass() != obj.getClass()) { return false; }
        Link other = (Link) obj;
        if (foo == null) { if (other.foo != null) { return false; } }
        else if (!foo.equals(other.foo)) { return false; }
        if (referenceId == null) { if (other.referenceId != null) { return false; } }
        else if (!referenceId.equals(other.referenceId)) { return false; }
        return true;
    }
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Referencable")
public class Referencable
{
    @XmlAttribute(name = "id", required = true)
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlID
    @XmlSchemaType(name = "ID")
    protected String id;
    public String getId() { return id; }
    public void setId(String value) { this.id = value; }

    @XmlAttribute(name = "name")
    protected String name;
    public String getName() { return name; }
    public void setName(String value) { this.name = value; }

    @Override public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override public boolean equals(Object obj) {
        if (this == obj) { return true; }
        if (!super.equals(obj)) { return false; }
        if (getClass() != obj.getClass()) { return false; }
        Referencable other = (Referencable) obj;
        if (name == null) { if (other.name != null) { return false; } }
        else if (!name.equals(other.name)) { return false; }
        return true;
    }
}

无法控制何时解析IDREF

解决办法:

  • 您可以从
    链接的hashcode
    中删除引用对象的hashcode。它仍然是一个一致的哈希代码(但性能较差)
  • 将集合列为一个列表,除非您有数百个条目,否则您几乎看不到性能影响
  • 使
    getLink()
    像这样

    protected List<Link> link;
    @XmlTransient
    private boolean reinit = false;
    public Set<Link> getLink() {
       if (!reinit) { 
          if(link != null) {
             link= new HashSet<Link>(link); 
          } else {
             link= new HashSet<Link>(); 
          }
          reinit = true
       } 
       return this.link;
    }
    
    受保护列表链接;
    @XmlTransient
    私有布尔reinit=false;
    公共集getLink(){
    如果(!reinit){
    如果(链接!=null){
    link=新哈希集(link);
    }否则{
    link=newhashset();
    }
    雷尼特=真
    } 
    返回此.link;
    }