Gson:有没有更简单的方法来序列化地图 [英] Gson: Is there an easier way to serialize a map

查看:113
本文介绍了Gson:有没有更简单的方法来序列化地图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自Gson项目的这个链接似乎表明我将拥有为类型化的Map序列化为JSON:

  public static class NumberTypeAdapter 
实现JsonSerializer< Number> ;,JsonDeserializer< Number> ;,
InstanceCreator< Number> {

public JsonElement serialize(Number src,Type typeOfSrc,JsonSerializationContext
context){
return new JsonPrimitive(src);

$ b $ public public deserialize(JsonElement json,Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
if(jsonPrimitive.isNumber()){
return jsonPrimitive.getAsNumber();
} else {
throw new IllegalStateException(期望的数字字段,但是是+ json);
}
}

公共数字createInstance(Type type){
return 1L;



public static void main(String [] args){
Map< String,Number> map = new HashMap< String,Number>();
map.put(int,123);
map.put(long,1234567890123456789L);
map.put(double,1234.5678D);
map.put(float,1.2345F);
类型mapType = new TypeToken< Map< String,Number>>(){} .getType();

Gson gson = new GsonBuilder()。registerTypeAdapter(Number.class,new
NumberTypeAdapter())。create();
String json = gson.toJson(map,mapType);
System.out.println(json);

地图< String,Number> deserializedMap = gson.fromJson(json,mapType);
System.out.println(deserializedMap);

$ / code>

很酷且很有效,但它看起来好像很多开销( 整个类型适配器类? )。我已经使用了其他JSON库,如JSONLib,他们让你以下面的方式构建地图:
$ b

  JSONObject json = new JSONObject ); (Entry< String,Integer> entry:map.entrySet()){
json.put(entry.getKey(),entry.getValue());
}

或者如果我有一个类似下面的自定义类:

  JSONObject json = new JSONObject(); 
for(Entry< String,MyClass> entry:map.entrySet()){
JSONObject myClassJson = JSONObject.fromObject(entry.getValue());
json.put(entry.getKey(),myClassJson);

$ / code>

这个过程比较手动,但需要的代码少一些,没有haivng为Number创建自定义类型适配器的开销,或者在大多数情况下为我自己的自定义类 创建自定义类型适配器。



这是使用Gson序列化地图的唯一方法,或者有人找到一种方法来打败Gson在以上链接中推荐的内容。

  Map< String,String> 

myMap = new HashMap< String,String>();
myMap.put(one,hello);
myMap.put(two,world);

Gson gson = new GsonBuilder()。create();
String json = gson.toJson(myMap);

System.out.println(json);

类型typeOfHashMap = new TypeToken< Map< String,String>>(){} .getType();
Map< String,String> newMap = gson.fromJson(json,typeOfHashMap); //这个类型必须匹配TypeToken
System.out.println(newMap.get(one));
System.out.println(newMap.get(two));

输出:

  {two:world,one:hello} 
hello
world


This link from the Gson project seems to indicate that I would have to do something like the following for serializing a typed Map to JSON:

    public static class NumberTypeAdapter 
      implements JsonSerializer<Number>, JsonDeserializer<Number>,
InstanceCreator<Number> {

    public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext
context) {
      return new JsonPrimitive(src);
    }

    public Number deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
        throws JsonParseException {
      JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive();
      if (jsonPrimitive.isNumber()) {
        return jsonPrimitive.getAsNumber();
      } else {
        throw new IllegalStateException("Expected a number field, but was " + json);
      }
    }

    public Number createInstance(Type type) {
      return 1L;
    }
  }

  public static void main(String[] args) {
    Map<String, Number> map = new HashMap<String, Number>();    
    map.put("int", 123);
    map.put("long", 1234567890123456789L);
    map.put("double", 1234.5678D);
    map.put("float", 1.2345F);
    Type mapType = new TypeToken<Map<String, Number>>() {}.getType();

    Gson gson = new GsonBuilder().registerTypeAdapter(Number.class, new
NumberTypeAdapter()).create();
    String json = gson.toJson(map, mapType);
    System.out.println(json);

    Map<String, Number> deserializedMap = gson.fromJson(json, mapType);
    System.out.println(deserializedMap);
  }

Cool and that works, but it seems like so much overhead (a whole Type Adapter class?). I have used other JSON libraries like JSONLib and they let you build a map in the following way:

JSONObject json = new JSONObject();
for(Entry<String,Integer> entry : map.entrySet()){
     json.put(entry.getKey(), entry.getValue());
}

Or if I have a custom class something like the following:

JSONObject json = new JSONObject();
for(Entry<String,MyClass> entry : map.entrySet()){
 JSONObject myClassJson =  JSONObject.fromObject(entry.getValue());
     json.put(entry.getKey(), myClassJson);
}

The process is more manual, but requires way less code and doesn't have the overhead of haivng to create a custom Type Adapter for Number or in most cases for my own custom class.

Is this the only way to serialize a map with Gson, or has anyone found a way that beats out what Gson recommends in the link above.

解决方案

Only the TypeToken part is neccesary (when there are Generics involved).

Map<String, String> myMap = new HashMap<String, String>();
myMap.put("one", "hello");
myMap.put("two", "world");

Gson gson = new GsonBuilder().create();
String json = gson.toJson(myMap);

System.out.println(json);

Type typeOfHashMap = new TypeToken<Map<String, String>>() { }.getType();
Map<String, String> newMap = gson.fromJson(json, typeOfHashMap); // This type must match TypeToken
System.out.println(newMap.get("one"));
System.out.println(newMap.get("two"));

Output:

{"two":"world","one":"hello"}
hello
world

这篇关于Gson:有没有更简单的方法来序列化地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆