JSON解析类库之Gson(2) --- 泛型对象Map、List与JSON字符串互转

JSON解析类库之Gson(2) --- 泛型对象Map、List与JSON字符串互转


---Gson类库学习, 生成与解析json数据,json字符串与Java对象互转


一、前言

本文延续前一篇文章,继续介绍基本的Gson用法。这篇文章我们将介绍,如何实现Java泛型对象,如Map<>,List<>等泛型集合与JSON字符串互转。

二、Gson的基本使用

泛型集合类型对象的序列化与反序列化
---------------------------------------------------------------------------------------------------
情况1 【非泛型】:Java数组的序列化与反序列化
数组与泛型不同,数组不是泛型。

Java Array ===》JSON String
JSON String ===》 Java Array
     
     
Gson  gson = new GsonBuilder()//
        .setPrettyPrinting()//格式化输出(序列化)
        .setDateFormat("yyyy-MM-dd HH:mm:ss") //序列化日期格式化输出
        .create();
User user1 = new User("1", "王重阳", new Date());
User user2 = new User("2", "郭靖", new Date());
User user3 = new User("3", "黄蓉", new Date());
User[] usersArray = { user1, user2, user3 }; //数组对象
/**
 * 序列化数组
 */
String jsonArrString = gson.toJson(usersArray);
System.out.println("数组序列化 ==》 " + jsonArrString);
/**
 * 数组序列化 ==》 [
  {
    "id": "1",
    "name": "王重阳",
    "birthday": "2017-05-03 16:06:50"
  },
  {
    "id": "2",
    "name": "郭靖",
    "birthday": "2017-05-03 16:06:50"
  },
  {
    "id": "3",
    "name": "黄蓉",
    "birthday": "2017-05-03 16:06:50"
  }
]
 */
/**
 * JSON字符串反序列化成数组对象,数组反序列化的类型参是可以直接用数组的class, 如 User [].class
 */
User[] usersArr = gson.fromJson(jsonArrString, User[].class);
for (int i = 0; i < usersArr.length; i++) {
    User u1 = usersArr[i];
    System.out.println("JSON字符串反序列化成数组对象 ==》 " + u1);
    /*
     * User对象 ==》 User [id=1, name=王重阳, birthday=Wed May 03 16:14:14 CST 2017]
       User对象 ==》 User [id=2, name=郭靖, birthday=Wed May 03 16:14:14 CST 2017]
       User对象 ==》 User [id=3, name=黄蓉, birthday=Wed May 03 16:14:14 CST 2017]
     */
}
注意:数组的字节码文件可以反射出具体的数组中的对象类型,但是List<User>不能直接用List<User>.class 或List.class。因为泛型编译成字节码时是擦除类型的,List<User>和List<Dept>在编译成字节码后完全一样,没区别。

泛型集合得用  new TypeToken(List<User>){}.getType() 作为反序列的第二个参数。


情况2 :Java  Map的序列化与反序列化

实体类:
       
       
public   class  Role {
    private String id;
    private String name;
    private String title;
    public Role() {
        super();
    }
    public Role(String id, String name, String title) {
        super();
        this.id = id;
        this.name = name;
        this.title = title;
    }
//为了代码简洁,这里移除了getter和setter方法、toString方法等
}

Map<String, List<? extends Object>>  ===》JSON String
JSON String   ===》  Map <String,  List <Object>>

       
       
package  com.chunlynn.gson;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
public class GsonTest10 {
    public static void main(String[] args) {
        Gson gson = new GsonBuilder()//
                .setPrettyPrinting()//格式化输出(序列化)
                .setDateFormat("yyyy-MM-dd HH:mm:ss") //序列化日期格式化输出
                .create();
        User user1 = new User("1", "王重阳", new Date());
        User user2 = new User("2", "郭靖", new Date());
        User user3 = new User("3", "黄蓉", new Date());
        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        Role role1 = new Role("1001", "chunlynn", "admin");
        Role role2 = new Role("1002", "jeff", "vistor");
        List<Role> roleList = new ArrayList<Role>();
        roleList.add(role1);
        roleList.add(role2);
        Map<String, List<? extends Object>> map = new LinkedHashMap<String, List<? extends Object>>(); //可以
        // Map<String, Object> map2 = new LinkedHashMap<String, Object>(); //可以
        // Map<String, List<Object>> map3 = new LinkedHashMap<String, List<Object>>();//这种不行,类型不匹配,put时无法添加
        map.put("users", userList);
        map.put("roles", roleList);
        /**
         * [7] Map泛型序列化成JSON字符串
         */
        String jsonStr = gson.toJson(map);
        System.out.println("Map泛型序列化成JSON字符串 ==》 " + jsonStr);
        /*Map泛型序列化成JSON字符串 ==》 
         {
          "users": [
            {
              "id": "1",
              "name": "王重阳",
              "birthday": "2017-05-03 17:04:12"
            },
            {
              "id": "2",
              "name": "郭靖",
              "birthday": "2017-05-03 17:04:12"
            },
            {
              "id": "3",
              "name": "黄蓉",
              "birthday": "2017-05-03 17:04:12"
            }
          ],
          "roles": [
            {
              "id": "1001",
              "name": "chunlynn",
              "title": "admin"
            },
            {
              "id": "1002",
              "name": "jeff",
              "title": "vistor"
            }
          ]
        }
        */
        /**
         * [8] JSON字符串反序列化成包含Map泛型类型
         */
        // 反序列化成那种泛型类型的设置,Map的泛型类型
        Type mtype = new TypeToken<Map<String, List<Object>>>() {
        }.getType();
        Map<String, List<Object>> retMap = gson.fromJson(jsonStr, mtype);
        System.out.println("retMap == > " + retMap);
        for (Map.Entry<String, List<Object>> p : retMap.entrySet()) {
            System.out.println("key ==" + p.getKey() + " , " + "value==" + p.getValue());
            /*
             * key ==users , value==[{id=1, name=王重阳, birthday=2017-05-03 17:55:16}, {id=2, name=郭靖, birthday=2017-05-03 17:55:16}, {id=3, name=黄蓉, birthday=2017-05-03 17:55:16}]
               key ==roles , value==[{id=1001, name=chunlynn, title=admin}, {id=1002, name=jeff, title=vistor}]
             */
        }
        Map<String, Object> retMap2 = gson.fromJson(jsonStr, mtype);
        System.out.println("retMap2 == > " + retMap2);
        for (Map.Entry<String, Object> p : retMap2.entrySet()) {
            System.out.println("key2 ==" + p.getKey() + " , " + "value2==" + p.getValue());
            /*
             * key2 ==users , value2==[{id=1, name=王重阳, birthday=2017-05-03 17:55:16}, {id=2, name=郭靖, birthday=2017-05-03 17:55:16}, {id=3, name=黄蓉, birthday=2017-05-03 17:55:16}]
               key2 ==roles , value2==[{id=1001, name=chunlynn, title=admin}, {id=1002, name=jeff, title=vistor}]
             */
        }
        Map<String, List<? extends Object>> retMap3 = gson.fromJson(jsonStr, mtype);
        System.out.println("retMap3 == > " + retMap3);
        for (Map.Entry<String, List<? extends Object>> p : retMap3.entrySet()) {
            System.out.println("key3 ==" + p.getKey() + " , " + "value3==" + p.getValue());
            /*
             * key3 ==users , value3==[{id=1, name=王重阳, birthday=2017-05-03 17:55:16}, {id=2, name=郭靖, birthday=2017-05-03 17:55:16}, {id=3, name=黄蓉, birthday=2017-05-03 17:55:16}]
               key3 ==roles , value3==[{id=1001, name=chunlynn, title=admin}, {id=1002, name=jeff, title=vistor}]
             */
        }
        /*
        retMap == > {users=[{id=1, name=王重阳, birthday=2017-05-03 17:43:05}, {id=2, name=郭靖, birthday=2017-05-03 17:43:05}, {id=3, name=黄蓉, birthday=2017-05-03 17:43:05}], 
roles=[{id=1001, name=chunlynn, title=admin}, {id=1002, name=jeff, title=vistor}]}
        retMap2 == > {users=[{id=1, name=王重阳, birthday=2017-05-03 17:43:05}, {id=2, name=郭靖, birthday=2017-05-03 17:43:05}, {id=3, name=黄蓉, birthday=2017-05-03 17:43:05}], 
roles=[{id=1001, name=chunlynn, title=admin}, {id=1002, name=jeff, title=vistor}]}
        retMap3 == > {users=[{id=1, name=王重阳, birthday=2017-05-03 17:43:05}, {id=2, name=郭靖, birthday=2017-05-03 17:43:05}, {id=3, name=黄蓉, birthday=2017-05-03 17:43:05}], 
roles=[{id=1001, name=chunlynn, title=admin}, {id=1002, name=jeff, title=vistor}]}
         */
    }
}

TypeToken 的构造方法是 protected 修饰的,所以上面才会写成new TypeToken<List<String>>(){}.getType()  而不是 new TypeToken<List<String>>().getType()  。


情况3 :Java Map高级的序列化与反序列化

★ Map的key为复杂对象形式

Map的存储结构式Key/Value形式,Key 和 Value可以是普通类型,也可以是自己写的JavaBean(本节),还可以是带有泛型的List(上节)。

实体类: 
    
    
public   class  Point {
    private int x;
    private int y;
    public Point(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }
//为了代码简洁,这里移除了getter和setter方法、toString方法等
}

测试类:
     
     
package  com.chunlynn.gson;
import java.util.LinkedHashMap;
import java.util.Map;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
public class GsonTest11 {
    public static void main(String[] args) {
        Gson gson = new GsonBuilder()//
                //.setPrettyPrinting()//格式化输出(序列化)
                .enableComplexMapKeySerialization() 支持Map的key为复杂对象的形式
                .create();
        /**
         * [9]普通Map<String,Object>形式的泛型序列化与反序列化,Map的key为简单String形式
         */
        Map<String, Point> map1 = new LinkedHashMap<String, Point>();
        map1.put("a", new Point(3, 4));
        map1.put("b", new Point(5, 6));
        String jsonStr1 = gson.toJson(map1);
        System.out.println("普通Map对象的序列化 ===》 " + jsonStr1);
        // 普通Map对象的序列化 ===》 {"a":{"x":3,"y":4},"b":{"x":5,"y":6}}
        Map<String, Point> retMap1 = gson.fromJson(jsonStr1, new TypeToken<Map<String, Point>>() {
        }.getType());
        for (String key : retMap1.keySet()) {
            System.out.println("key=" + key + ", values=" + retMap1.get(key));
        }
        //key=a, values=Point [x=3, y=4]
        //key=b, values=Point [x=5, y=6]
        /**
         * [10]特殊Map<Object,String>形式的泛型序列化与反序列化,Map的key为复杂对象形式
         */
        Map<Point, String> map2 = new LinkedHashMap<Point, String>();
        map2.put(new Point(7, 8), "c");
        map2.put(new Point(9, 10), "d");
        String jsonStr2 = gson.toJson(map2);
        System.out.println("Map的key为复杂对象形式的Map对象的序列化 ===》 " + jsonStr2);
        //Map的key为复杂对象形式的Map对象的序列化 ===》 [[{"x":7,"y":8},"c"],[{"x":9,"y":10},"d"]]
        Map<Point, String> retMap2 = gson.fromJson(jsonStr2, new TypeToken<Map<Point, String>>() {
        }.getType());
        for (Point pKey : retMap2.keySet()) {
            System.out.println("key=" + pKey + ", values:" + retMap2.get(pKey));
        }
        // key=Point [x=7, y=8], values:c
        // key=Point [x=9, y=10], values:d
    }
}
Map、List泛型的完结。


  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值