我在XML文件中有一些数据,我想用JAXB解组到MyHashMap中。 MyObject有一个String名称,这是我的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;
}
}
它在Java 7中运行良好(根据this的问题因为一个错误),但在Java 8中没有。 在Java 8中,JAXB获取ListObject并添加Elemts而不是使用setter。
所以我添加了一个&#34;返回null&#34;如果列表为空。 显然JAXB然后设置一个空列表,然后添加元素,这显然不适用于我的代码。 是否有可能告诉JAXB将Elements添加到列表中并仅调用setter?
答案 0 :(得分:1)
您可以使用Map,因为JAXB将编组并解组它。 (参见https://jaxb.java.net/tutorial/section_6_2_1-A-Survey-Of-JAXB-Annotations.html)为避免重复名称,请在MyObject中使用@XmlTransient
进行注释。
另一种方法是使用适配器;您必须将Map包装到父元素中。见https://jaxb.java.net/tutorial/section_6_2_9-Type-Adapters-XmlJavaTypeAdapter.html
另一种可能性是使用更简单的方法,根元素类的实现略有不同。它可以让你像地图一样使用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
}