Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何让JAXB在向列表添加元素后调用setter?_Java_Xml_Jaxb - Fatal编程技术网

Java 如何让JAXB在向列表添加元素后调用setter?

Java 如何让JAXB在向列表添加元素后调用setter?,java,xml,jaxb,Java,Xml,Jaxb,我想用JAXB将XML文件中的一些数据解组到MyHashMap中。 MyObject有一个字符串名,它是HashMap中的键 为了防止将键/名称信息两次写入我的XML文件(一次作为MyObject的名称,一次作为MyHashMap的键),因此我为ArrayList添加了setter和getter,用于向MyHashMap中添加/读取数据 @XmlRootElement public class MyHashMap extends HashMap<String, MyObject> i

我想用JAXB将XML文件中的一些数据解组到MyHashMap中。 MyObject有一个字符串名,它是HashMap中的键

为了防止将键/名称信息两次写入我的XML文件(一次作为MyObject的名称,一次作为MyHashMap的键),因此我为ArrayList添加了setter和getter,用于向MyHashMap中添加/读取数据

@XmlRootElement
public class MyHashMap extends HashMap<String, MyObject> implements Serializable {

    public MyHashMap() {
        super();
    }

    @XmlElement(name = "MyObject")
    public void setMyObjectsArrayList(ArrayList<MyObject> MyObjectList) {
        for (MyObject myObject : MyObjectList) {
            this.put(myObject.getName(), myObject);
        }
    }

    public ArrayList<MyObject> getMyObjectsArrayList() {
        if (this.isEmpty()) { // Added this to get my setter called
            return null;
        }
        ArrayList<MyObject> MyObjectList = new ArrayList<MyObject>();
        MyObjectList.addAll(this.values());
        return MyObjectList;
    }
}
@XmlRootElement
公共类MyHashMap扩展HashMap实现可序列化{
公共MyHashMap(){
超级();
}
@XmlElement(name=“MyObject”)
public void setMyObjectsArray列表(ArrayList MyObjectList){
用于(MyObject MyObject:MyObject列表){
this.put(myObject.getName(),myObject);
}
}
公共阵列列表getMyObjectsArrayList(){
如果(this.isEmpty()){//添加此项以调用我的setter
返回null;
}
ArrayList MyObjectList=新建ArrayList();
MyObjectList.addAll(this.values());
返回MyObjectList;
}
}
它在Java7中工作得很好(根据的andswer,因为有一个bug),但在Java8中没有。 在Java8中,JAXB获取ListObject并添加Elemts,而不是使用setter

因此,如果列表为空,我添加了一个“returnnull”。 显然,JAXB然后设置一个空列表,然后添加元素,这显然不适用于我的代码。
是否有可能告诉JAXB将元素添加到列表中,然后才调用setter?

您可以使用Map,因为JAXB会封送和解封它。(参见)为避免名称重复,请在MyObject中使用
@xmltransive
对其进行注释

另一种方法是使用适配器;您必须将地图包装到父元素中。看

还有一种可能性是使用一种更简单的方法,对根元素类的实现略有不同。它可以让您像使用映射一样使用MyHashMap,并避免所有肮脏的把戏,尽管访问器调用起来有点不方便。当然,您也可以实现Map,并且可以干净方便地完成它,但这需要编写更多的代码

@XmlRootElement
public class MyHashMap {
    private boolean dirty = false;
    private Map<String,MyObject> str2obj;
    private List<MyObject> myObjects = new ArrayList<>();

    @XmlElement(name = "MyObject")
    List<MyObject> getMyObjects(){
        dirty = true;
        return myObjects();
    }

    // variant 1: expose str2obj
    @XmlTransient
    public Map<String,MyObject> getStr2Obj(){
        if( dirty ) rebuild();
        return str2obj;
    }

    private void rebuild(){
        str2obj.clear();
        for( MyObject myObject: myObjects ){
            str2obj.put(mmyObject.getName(), myObject );
        }
        dirty = false;
    }

    // variant 2: delegate put, get, and other methods
    // use the same approach
}
@XmlRootElement
公共类MyHashMap{
私有布尔脏=假;
私有地图str2obj;
私有列表myObjects=newarraylist();
@XmlElement(name=“MyObject”)
列出getMyObject(){
肮脏=真实;
返回myObjects();
}
//变体1:暴露str2obj
@XmlTransient
公共地图getStr2Obj(){
如果(脏)重建();
返回str2obj;
}
私有void重建(){
str2obj.clear();
用于(MyObject MyObject:MyObject){
str2obj.put(mmyObject.getName(),myObject);
}
脏=假;
}
//变量2:委托put、get和其他方法
//使用相同的方法
}