繁体   English   中英

Json map 到 java map

[英]Json map into java map

我有以下 json 文件

[{
        "en": {
            "key1": "Ap",
            "key2": "ap2"
        }
    },

    {
        "ar": {
            "key1": "Ap",
            "key2": "ap2"
        }
    }
]

我想在 Java 中创建一个 Map 例如键是语言(如 en 或 ar),值是 object。 像这样的东西。

public class Category {
    private String key1;
    private String key2;
}

    Type type = new TypeToken<Map<String, Category>>() {}.getType();
    Gson gson = new Gson();

    InputStream in = MyClass.class.getResourceAsStream("/categories.json");
    String text = IOUtils.toString(in, StandardCharsets.UTF_8);
    Map<String, Category> map = gson.fromJson(text, type);

但是当我运行这段代码时,我得到了错误:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 3 path $[0]

我的 Json 结构是错误的还是有更简单的方法来 map 这个?

尝试阅读此 json 文件

 {
  "ar": {
    "key1": "Ap",
    "key2": "ap2"
  },
  "en": {
    "key1": "Ap",
    "key2": "ap2"
  }
}

上面的 json 是JsonObject的集合,如列表或数组,所以只需将其解析为Map对象的List

Type type = new TypeToken<List<Map<String, Category>>>() {}.getType();

您的 json 是地图列表,而不仅仅是地图。 所以你必须将它添加到声明的类型中。

尝试这个:

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Category {
    private String key1;
    private String key2;

    @Override
    public String toString() {
        return "Category{" +
                "key1='" + key1 + '\'' +
                ", key2='" + key2 + '\'' +
                '}';
    }

    public static void main(String[] args) {

        String json = "[{\n" +
                "        \"en\": {\n" +
                "            \"key1\": \"Ap\",\n" +
                "            \"key2\": \"ap2\"\n" +
                "        }\n" +
                "    },\n" +
                "\n" +
                "    {\n" +
                "        \"ar\": {\n" +
                "            \"key1\": \"Ap\",\n" +
                "            \"key2\": \"ap2\"\n" +
                "        }\n" +
                "    }\n" +
                "]";

        Type type = new TypeToken<List<Map<String, Category>>>() {}.getType();
        Gson gson = new Gson();

        List<Map<String, Category>> maps = gson.fromJson(json, type);
        System.out.println(maps);
    }
}

您的输入是一个包含两个对象的 json 数组。 但是,您的目标变量“类型”是 Object 类型,而不是“对象数组”。 简单来说,Map 不能存储数组。

让我们采取一种更简单的方法来解决这个问题(不是推荐的方法)。 如果我们手动将 map 转换为地图数组,则如下所示:

yourJson -> [Map1(en,category1(Ap,ap2)),Map2(en,category2(Ap,ap2))]

即一组地图

因此,在 java 等效项中,这变为:

Type typeOfT2 = new TypeToken<ArrayList<HashMap<String, Category>>>() {}.getType();
List<HashMap<String, Category>> list = gson.fromJson(text, typeOfT2);

我们得到了我们想要的,但是有更好的方法来做到这一点。 为此,我们需要 Jackson 而不是 Gson。(有人可能会添加基于 Gson 的解决方案,很确定存在比上述更清洁的解决方案)。 这里我们将使用来自com.fasterxml.jackson.databind.ObjectMapperObjectMapper

ObjectMapper om = new ObjectMapper();
List<Map.Entry<String, Category>> listx = om.readValue(text, ArrayList.class);

如果您打印listx 你可以看到这个(覆盖类别类的toString() ):

[{en={key1=Ap, key2=ap2}}, {ar={key1=Ap, key2=ap2}}]

listx是 json 的最准确表示,而不是 Map。

现在,如果您需要 map,我将把它作为练习留给您,以了解如何将 Map.Entry 列表转换为 Map 实现。

PS.:这里的第一个长答案。 为任何错误道歉。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM