【问题标题】:Map a JSON string into HashMap将 JSON 字符串映射到 HashMap
【发布时间】:2020-02-23 15:30:32
【问题描述】:

考虑以下 JSON:

[
  {
    "map": "TEST",
    "values": [
      "test",
      "test2"
    ]
  },
  {
    "map": "TEST1",
    "values": [
      "test",
      "test3",
      "test4"
    ]
  },
  {
    "map": "TEST2",
    "values": [
      "test4",
      "test2",
      "test5",
      "test2"
    ]
  }
]

已通过 getResourceAsString 函数加载到字符串中。 如何制作一个 HashMap,其中我的键是“map”字段,而我的值是“values”字段的数组? 我在其他类似问题中尝试了许多解决方案,但没有任何效果。

这是我的代码的开头:

    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

但我不知道如何将它分配给 Map,readValue 方法似乎没有给出正确的东西

【问题讨论】:

  • 为什么不将其解析为地图列表,然后将其转换为单个地图?
  • 如何做到这一点?当我尝试将其分配给地图列表时,我摆脱了数组异常 Type mapType = new TypeToken>(){}.getType(); Map son = new Gson().fromJson(str, mapType); -> 应为 BEGIN_ARRAY,但为 BEGIN_OBJECT
  • Convert JSON to Map的可能重复

标签: java arrays json dictionary


【解决方案1】:

您可以将其反序列化为List<Map<String, Object>>,然后再转换为Map

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./src/main/resources/test.json");

        ObjectMapper mapper = new ObjectMapper();

        TypeReference rootType = new TypeReference<List<Map<String, Object>>>() { };
        List<Map<String, Object>> root = mapper.readValue(jsonFile, rootType);
        Map<String, Object> result = root.stream()
                 .collect(Collectors.toMap(
                         m -> m.get("map").toString(),
                         m -> m.get("values")));
        System.out.println(result);
    }
}

上面的代码打印:

{TEST2=[test4, test2, test5, test2], TEST=[test, test2], TEST1=[test, test3, test4]}

【讨论】:

  • 我会投赞成票,因为使用 TypeReference 是一种类型安全且可读的解决方案。但是,Stream.reduce() 不适用于可变数据类型 - 这就是 Stream.collect() 的用途!
  • @drekbour,你当然是对的。 collect 更适合这里。
【解决方案2】:

你可以这样做:

ArrayNode rootNode = (ArrayNode) new ObjectMapper().readTree(...);
Map<String, List<String>> map = new LinkedHashMap<>();
for (int i = 0; i < rootNode.size(); i++) {
    JsonNode objNode = rootNode.get(i);
    String name = objNode.get("map").textValue();
    ArrayNode valuesNode = (ArrayNode) objNode.get("values");
    List<String> values = new ArrayList<>(valuesNode.size());
    for (int j = 0; j < valuesNode.size(); j++)
        values.add(valuesNode.get(j).textValue());
    map.put(name, values);
}

结果

{TEST=[test, test2], TEST1=[test, test3, test4], TEST2=[test4, test2, test5, test2]}

【讨论】:

    【解决方案3】:

    您可以将List&lt;Map&lt;Object,Object&gt;&gt; 用于此 json,因为它是 3 个对象的列表,因此它不能直接转换为 HashMap,所以试试这个:

    String json = "[{\"map\":\"TEST\",\"values\":[\"test\",\"test2\"]},{\"map\":\"TEST1\",\"values\":[\"test\",\"test3\",\"test4\"]},{\"map\":\"TEST2\",\"values\":[\"test4\",\"test2\",\"test5\",\"test2\"]}]";
    
    List<Map<Object, Object>> jsonObj = mapper.readValue(json, List.class);
    

    【讨论】:

      猜你喜欢
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 2016-12-09
      • 2012-01-23
      相关资源
      最近更新 更多