3

我想用Jackson将 JSON 转换为 HashMap 。这是我的 JSON:

String json = "[{\"Opleidingen\":[{\"name\":\"Bijz. trajecten zorg en welzijn\",\"afk\":\"BTZW\",\"id\":\"0\"},{\"name\":\"Bouwkunde\",\"afk\":\"Bwk\",\"id\":\"14\"},{\"name\":\"Electrotechniek / mechatronica\",\"afk\":\"EltMe\",\"id\":\"15\"},{\"name\":\"Extern\",\"afk\":\"Extern\",\"id\":\"16\"},{\"name\":\"Gezondheidszorg\",\"afk\":\"Zorg\",\"id\":\"17\"},{\"name\":\"Handel\",\"afk\":\"Hand\",\"id\":\"18\"},{\"name\":\"Horeca\",\"afk\":\"Hor\",\"id\":\"19\"},{\"name\":\"Ict\",\"afk\":\"ICT\",\"id\":\"20\"},{\"name\":\"Maatschappelijke zorg\",\"afk\":\"MZ\",\"id\":\"21\"},{\"name\":\"Onderwijs assistent / pedagogisch werk\",\"afk\":\"OAPW\",\"id\":\"22\"},{\"name\":\"Tab / brug\",\"afk\":\"TAB\",\"id\":\"23\"},{\"name\":\"Werktuigbouw / maritieme techniek\",\"afk\":\"WtbMt\",\"id\":\"24\"},{\"name\":\"Zakelijke dienstverlening\",\"afk\":\"TAB\",\"id\":\"25\"}]},{\"Klassen\":[{\"name\":\"V2ZWA\",\"cat\":\"BTZW\",\"id\":\"1\"},{\"name\":\"V2ZWB\",\"cat\":\"Bwk\",\"id\":\"2\"},{\"name\":\"V2ZWB\",\"cat\":\"BTZW\",\"id\":\"3\"},{\"name\":\"V3B2A\",\"cat\":\"BTZW\",\"id\":\"3\"},{\"name\":\"V3B2B\",\"cat\":\"BTZW\",\"id\":\"4\"},{\"name\":\"V3B2C\",\"cat\":\"BTZW\",\"id\":\"5\"},{\"name\":\"V3B2D\",\"cat\":\"BTZW\",\"id\":\"6\"},{\"name\":\"V3B2E\",\"cat\":\"BTZW\",\"id\":\"7\"},{\"name\":\"V3B3A\",\"cat\":\"BTZW\",\"id\":\"8\"},{\"name\":\"V3B3B\",\"cat\":\"BTZW\",\"id\":\"9\"},{\"name\":\"V3B3C\",\"cat\":\"BTZW\",\"id\":\"10\"},{\"name\":\"VWA\",\"cat\":\"BTZW\",\"id\":\"11\"},{\"name\":\"VWB\",\"cat\":\"BTZW\",\"id\":\"12\"},{\"name\":\"VWC\",\"cat\":\"BTZW\",\"id\":\"13\"}]}]"; 

我希望我填写我得到名字的 ID,所以:result.get("13");返回VWCresult.get("0");返回Bijz. trajecten zorg en welzijn

我试过这个:

try {
    @SuppressWarnings("unchecked")
    ArrayList<LinkedHashMap<?, ?>> result = new ObjectMapper().readValue(json, ArrayList.class);
    System.out.println(result.get(1).get("id"));
} catch (JsonParseException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

但这是以下内容result.get(1);

I/System.out(809): {Klassen=[{name=V2ZWA, cat=BTZW, id=1}, {name=V2ZWB, cat=Bwk, id=2}, {name=V2ZWB, cat=BTZW, id=3}, {name=V3B2A, cat=BTZW, id=3}, {name=V3B2B, cat=BTZW, id=4}, {name=V3B2C, cat=BTZW, id=5}, {name=V3B2D, cat=BTZW, id=6}, {name=V3B2E, cat=BTZW, id=7}, {name=V3B3A, cat=BTZW, id=8}, {name=V3B3B, cat=BTZW, id=9}, {name=V3B3C, cat=BTZW, id=10}, {name=VWA, cat=BTZW, id=11}, {name=VWB, cat=BTZW, id=12}, {name=VWC, cat=BTZW, id=13}]}

我也试过没有杰克逊:

for (int i = 0; i < jObject.length(); i++) {
       JSONArray opleidingen = jObject.getJSONObject(i).getJSONArray("Opleidingen");
       for (int i2 = 0; i2 < opleidingen.length(); i2++) {
           outMap.put(opleidingen.getJSONObject(i2).getString("id"), opleidingen.getJSONObject(i2).getString("name"));
       }
       JSONArray klassen = jObject.getJSONObject(i).getJSONArray("Klassen");
       for (int i3 = 0; i3 < klassen.length(); i3++) {
           outMap.put(klassen.getJSONObject(i3).getString("id"), klassen.getJSONObject(i3).getString("name"));
       }
}

但这都行不通。

是否可以将我的 JSON 转换为 HashMap(并且当给出 ID 时它返回名称)?

(ArrayList 类可以在这里找到)

4

2 回答 2

2

我认为,您应该将反序列化逻辑与最后检索名称的方式分开。对于反序列化,请尽可能使用简单的方法。例如,您可以创建描述 JSON 的 POJO 类。请参见下面的示例。POJO类:

class EntitiesOwner {

    private String name;
    private List<Entity> entities;

    @JsonAnySetter
    public void setProperties(String name, List<Entity> entities) {
        this.name = name;
        this.entities = entities;
    }

    public String getName() {
        return name;
    }

    public List<Entity> getEntities() {
        return entities;
    }

    @Override
    public String toString() {
        return "EntitiesOwner [name=" + name + ", entities=" + entities + "]";
    }
}

class Entity {

    private int id;
    private String afk;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAfk() {
        return afk;
    }

    public void setAfk(String afk) {
        this.afk = afk;
    }

    public void setCat(String cat) {
        this.afk = cat;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Entity [id=" + id + ", afk=" + afk + ", name=" + name + "]";
    }
}

现在您可以通过这种方式轻松反序列化它:

ObjectMapper mapper = new ObjectMapper();

EntitiesOwner[] owners = mapper.readValue(json, EntitiesOwner[].class);
System.out.println(Arrays.toString(owners));

上面的程序打印:

[EntitiesOwner [name=Opleidingen, entities=[Entity [id=0, afk=BTZW, name=Bijz. trajecten zorg en welzijn], Entity [id=14, afk=Bwk, name=Bouwkunde], Entity [id=15, afk=EltMe, name=Electrotechniek / mechatronica], Entity [id=16, afk=Extern, name=Extern], Entity [id=17, afk=Zorg, name=Gezondheidszorg], Entity [id=18, afk=Hand, name=Handel], Entity [id=19, afk=Hor, name=Horeca], Entity [id=20, afk=ICT, name=Ict], Entity [id=21, afk=MZ, name=Maatschappelijke zorg], Entity [id=22, afk=OAPW, name=Onderwijs assistent / pedagogisch werk], Entity [id=23, afk=TAB, name=Tab / brug], Entity [id=24, afk=WtbMt, name=Werktuigbouw / maritieme techniek], Entity [id=25, afk=TAB, name=Zakelijke dienstverlening]]], EntitiesOwner [name=Klassen, entities=[Entity [id=1, afk=BTZW, name=V2ZWA], Entity [id=2, afk=Bwk, name=V2ZWB], Entity [id=3, afk=BTZW, name=V2ZWB], Entity [id=3, afk=BTZW, name=V3B2A], Entity [id=4, afk=BTZW, name=V3B2B], Entity [id=5, afk=BTZW, name=V3B2C], Entity [id=6, afk=BTZW, name=V3B2D], Entity [id=7, afk=BTZW, name=V3B2E], Entity [id=8, afk=BTZW, name=V3B3A], Entity [id=9, afk=BTZW, name=V3B3B], Entity [id=10, afk=BTZW, name=V3B3C], Entity [id=11, afk=BTZW, name=VWA], Entity [id=12, afk=BTZW, name=VWB], Entity [id=13, afk=BTZW, name=VWC]]]]

对于解决实体,我建议创建可以帮助您解决此问题的新类。例如:

class EntityResolver {

    private Map<Integer, Entity> entities;

    public EntityResolver(EntitiesOwner[] owners) {
        entities = new HashMap<Integer, Entity>(owners.length);
        for (EntitiesOwner owner : owners) {
            for (Entity entity : owner.getEntities()) {
                entities.put(entity.getId(), entity);
            }
        }
    }

    public Entity getById(int id) {
        return entities.get(id);
    }
}

简单用法:

EntityResolver resolver = new EntityResolver(owners);
System.out.println(resolver.getById(0).getName());
System.out.println(resolver.getById(13).getName());

上面的程序打印:

Bijz. trajecten zorg en welzijn
VWC
于 2013-10-21T10:51:01.417 回答
0

默认情况下,JSON 中的列表映射到 Java 中的 ArrayList。可能有一种方法可以直接将列表反序列化为 HashMap,但即便如此,该方法也会非常复杂。为什么不将您的 JSON 列表反序列化为 ArrayList 并进行一些后处理以获取 HashMap?像这样的东西:

public Map<Integer, String> listToMap(List<Object> list) {
    Map<Integer, String> map = new HashMap<>();

    for (Object obj : list) {
        // you might want to try-catch all casts, some data might be invalid
        Map<String, Object> elt = (Map<String, Object>) obj;

        Integer id = (Integer) elt.get("id");
        String name = (String) elt.get("name");
        map.put(id, name);
    }

    return map;
}

编辑

我没有明确说明如何获取列表以提供给上述方法。json在下面的代码段中,我使用了您在问题中声明的字符串。为了完整起见,请参阅Jackson 文档中的原始数据绑定。

List<Object> inputData = new ObjectMapper().readValue(json, List.class);
Map<String, Object> inputMap = (Map<String, Object>) inputData.get(0);
List<Object> opleidingen = (List<Object>) inputMap.get("Opleidingen");
List<Object> klassen = (List<Object>) inputMap.get("Klassen");

Map<Integer, String> opleidingenMap = listToMap(opleidingen);
Map<Integer, String> klassenMap = listToMap(klassen);

现在您可以按照您描述的方式使用这两个地图:

opleidingenMap.get(25)

"Zakelijke dienstverlening"

请注意,这样您最终会得到一个单独的 opleidingen 和 klassen 地图。如果您希望在一张地图中包含所有元素,则可以制作这样的地图:

Map<Integer, String> fullMap = new HashMap<>();
fullMap.putAll(opleidingenMap);
fullMap.putAll(klassen);

请注意,这假设没有与某些 klas 具有相同 id 的 opleiding。

于 2013-10-21T07:59:56.343 回答