我有以下json文件
[{
"en": {
"key1": "Ap",
"key2": "ap2"
}
},
{
"ar": {
"key1": "Ap",
"key2": "ap2"
}
}
]
我想用Java创建一个Map,例如键是语言(例如en或ar),值是一个对象。像这样的东西。
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结构是否错误,或者有更简单的方法来映射它?
答案 0 :(得分:0)
尝试读取此json文件
df=pd.DataFrame({'date':['20190606','20190610','20190708','20190805','20190909','20190930'],'number':[3,5,4,1,0,0], 'avg_last_2m':[None,3,4,4,1,0.5]})
df["date"]=pd.to_datetime(df.date, format="%Y%m%d")
df["date_minus_2m"]=df["date"]-pd.DateOffset(months=2)
def avg_2m (row):
avg_2m = df[(df.date>=row["date_minus_2m"])&(df.date<=row["date"])]["number"].mean()
return avg_2m
df["avg_2m"]=df.apply(avg_2m, axis=1)
答案 1 :(得分:0)
上面的json是JsonObject
的集合,例如列表或数组,因此只需将其解析为List
个对象的Map
Type type = new TypeToken<List<Map<String, Category>>>() {}.getType();
答案 2 :(得分:0)
您的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);
}
}
答案 3 :(得分:0)
您的输入是一个带有两个对象的json数组。但是,目标变量“类型”是对象类型,而不是“对象数组”。简单来说,地图无法存储 数组。
让我们对这个问题采取更简单的方法(而不是推荐的方法)。如果我们将地图手动转换为地图数组,则将如下所示:
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的解决方案,因此可以确定存在比上述更干净的解决方案)。在这里,我们将使用ObjectMapper
com.fasterxml.jackson.databind.ObjectMapper
ObjectMapper om = new ObjectMapper();
List<Map.Entry<String, Category>> listx = om.readValue(text, ArrayList.class);
如果打印listx
。您可以看到以下内容(覆盖Category类的toString()
):
[{en={key1=Ap, key2=ap2}}, {ar={key1=Ap, key2=ap2}}]
listx
是json的最准确表示,而不是Map。
现在,如果您需要地图,那么我将作为练习,教您如何将Map.Entry列表转换为Map实现。
PS .:这里是第一个长答案。如有任何错误,我们深表歉意。