前面一篇文章我介紹了Gson的解析的基本方法。但我們在享受Gson解析的高度封裝帶來的便利時,有時可能會遇到一些特殊情況,比如json數據中的字段key是動態可變的時候,由于Gson是使用靜態注解的方式來設置實體對象的,因此我們很難直接對返回的類型來判斷。但Gson在解析過程中如果不知道解析的字段,就會將所有變量存儲在一個Map中,我們只要實例化這個map就能動態地取出key和value了。
先給出一段jsondata,這是天氣預報的數據,其中day_20151002這種key是隨日期而變化的,在實體類中就不能當做靜態變量來處理,我們就通過map來取出其映射對象。
{?"resultcode":"200","reason":"successed!",
"result":{
"sk":{
"temp":"24","wind_direction":"東北風","wind_strength":"2級","humidity":"28%","time":"17:38"
},
"today":{
"temperature":"15℃~26℃","weather":"多云轉晴","wind":"東北風微風","week":"星期日","city":"桂林","date_y":"2015年10月11日","dressing_index":"舒適","dressing_advice":"建議著長袖T恤、襯衫加單褲等服裝。年老體弱者宜著針織長袖襯衫、馬甲和長褲。","uv_index":"弱","comfort_index":"","wash_index":"較適宜","travel_index":"較適宜","exercise_index":"較適宜","drying_index":""
},
"future":{
"day_20151011":{"temperature":"15℃~26℃","weather":"多云轉晴","wind":"東北風微風","week":"星期日","date":"20151011"},
"day_20151012":{"temperature":"16℃~27℃","weather":"晴轉多云","wind":"微風","week":"星期一","date":"20151012"},
"day_20151013":{"temperature":"16℃~26℃","weather":"多云轉晴",,"wind":"微風","week":"星期二","date":"20151013"},
"day_20151014":{"temperature":"17℃~27℃","weather":"晴","wind":"北風微風","week":"星期三","date":"20151014"},
"day_20151015":{"temperature":"17℃~28℃","weather":"晴","wind":"北風微風","week":"星期四","date":"20151015"},
"day_20151016":{"temperature":"17℃~30℃","weather":"晴","wind":"北風微風","week":"星期五","date":"20151016"},
"day_20151017":{"temperature":"17℃~30℃","weather":"晴","wind":"北風微風","week":"星期六","date":"20151017"}
}
},
"error_code":0
}
實體類中放上set、get和toString方法就太長了,這里就沒有加上去。
public?class?FutureDay?{
private?String?temperature;
private?String?weather;
private?String?wind;
private?String?week;
private?String?date;
}
public?class?Result?{
private?Sk?sk;
private?Today?today;
private?Map?future;
}
public?class?Sk?{
private?String?temp;
private?String?wind_direction;
private?String?wind_strength;
private?String?humidity;
private?String?time;
}
public?class?Today?{
private?String?temperature;
private?String?weather;
private?String?week;
private?String?city;
private?String?date_y;
private?String?dressing_index;
private?String?dressing_advice;
private?String?uv_index;
private?String?comfort_index;
private?String?wash_index;
private?String?travel_index;
private?String?exercise_index;
private?String?drying_index;
}
public?class?Response?{
private?String?resultcode;
private?String?reason;
private?String?error_code;
private?Result?result;
}
import?java.io.BufferedReader;
import?java.io.FileReader;
import?java.util.Map;
import?weather.*;
import?com.google.gson.Gson;
public?class?GsonParseDynamicKey?{
public?static??void?main(?String?args?[]){
String?jsondata?=?readJsonFile();//從文件中讀取出json字符串,并打印出來
Gson?gson?=?new?Gson();
System.out.println("Start?Gson?parse?jsondata");
Response?response?=?gson.fromJson(jsondata,?Response.class);
System.out.println(response.toString());
System.out.println(response.getResult().getSk().toString());
System.out.println(response.getResult().getToday().toString());
Map?future?=?response.getResult().getFuture();?//對動態的key,來創建map,間接從中取出實體類futrue。
System.out.println("Keyset?method");?????????????????????//這里取出value的方法有兩種keySet()?entrySet().都給出了遍歷的方法
for?(String?key:future.keySet()){????????????????????????//遍歷取出key,再遍歷map取出value。
System.out.println("key:"+key);
System.out.println(future.get(key).toString());
}
System.out.println("Entryset?method");
for?(Map.Entry?pair:future.entrySet()){//遍歷取出鍵值對,調用getkey(),getvalue()取出key和value。
System.out.println("key:"+pair.getKey());
System.out.println(pair.getValue().toString());
}
}
這里順便一提遍歷Map的兩種方法keySet(),entrySet()的差別。
keySet()方法返回的是key的集合set,entrySet()返回的是鍵值對的集合set。雖然兩者從set遍歷取出元素的方法是一樣的,但是根據這個元素取出value的效率有些不同。前者取出的元素是key,還要去原map中遍歷取出value。
后者取出的元素是鍵值對,直接調用getkey(),getvalue()方法就能快速取出key和value。顯然在map中存在大量鍵值對時,使用entrySet()來取出value的效率更高。