Gson——Map的映射

原文鏈接:Gson — Mapping of Maps

作者:Norman Peitek

翻譯:簽到錢就到

在發(fā)布了多篇關(guān)于如何處理不同數(shù)據(jù)類型的文章之后祥国,我們會在這篇文章中處理Java的Map類型。你會學(xué)習(xí)如何使用Gson庫去序列化(反序列化)Java的Map斯嚎。

當(dāng)然,這不是我們Gson系列里唯一的一篇文章凌摄,如果你對其他的主題感興趣另锋,可以看一下我們的大綱:

Gson系列概覽

  1. 用java-JSON實現(xiàn)序列化合反序列化
  2. 嵌套對象的映射
  3. 數(shù)組和列表對象的映射
  4. Map的映射
  5. Mapping of Sets
  6. Mapping of Null Values
  7. Gson Model Annotations — How to Ignore Fields with @Expose
  8. Gson Model Annotations — How to Change the Naming of Fields with @SerializedName
  9. Gson Builder — Basics & Naming Policies
  10. Gson Builder — Force Serialization of null Values
  11. Gson Builder — Exclusion Strategies
  12. Gson Builder — Relax Gson with Lenient
  13. Gson Builder — Special Values of Floats & Doubles
  14. Gson Builder — Model Versioning
  15. Gson Builder — Formatting of Dates & Custom Date/Time Mapping
  16. Gson Builder — Pretty Printing
  17. Gson Builder — HTML Escaping

Java中Map的序列化

Java的Map是一個非常靈活的數(shù)據(jù)類型俊柔,可以被用在各種各樣的場景中。它允許我們開發(fā)者用Java語言去物化許多真實世界的情況枫夺。由于Java的Map使用非常廣泛磅网,我們可能不會覆蓋到你正在用的案例,但將會覆蓋到所有的方法筷屡。

讓我們用一個場景來開始涧偷,你的應(yīng)用有員工姓名的列表,你被要求去實現(xiàn)一個以某個特定字母開頭的所有員工展示界面毙死。例如燎潮,用戶可以選擇字母A,此時扼倘,你的應(yīng)用會返回三個匹配的員工名字:Andreas确封、AdenArnold。第一次迭代只是列出了所有名字的列表再菊,但是性能往往是不夠的爪喘。因此,轉(zhuǎn)去使用HashMap實現(xiàn)纠拔,第一個字母作為鍵(Key)(如:A)秉剑,值將是一個名字的列表。

如果我們創(chuàng)建我們的HashMap,我們的Java代碼將會是這樣:

HashMap<String, List<String>> employees = new HashMap<>();  
employees.put("A", Arrays.asList("Andreas", "Arnold", "Aden"));  
employees.put("C", Arrays.asList("Christian", "Carter"));  
employees.put("M", Arrays.asList("Marcus", "Mary")); 

Map的序列化與其他類型是一樣的稠诲,你可以將其直接傳給Gson侦鹏,Gson會正確地處理:

Gson gson = new Gson();  
String employeeJson = gson.toJson(employees); 

返回的JSON數(shù)據(jù):

{
  "M": [
    "Marcus",
    "Mary"
  ],
  "C": [
    "Christian",
    "Carter"
  ],
  "A": [
    "Andreas",
    "Arnold",
    "Aden"
  ]
}

每個鍵(A,CM)都有自己的名字列表诡曙,這正是我們想要的。

Java中Map的反序列化

如果你看了前面一節(jié)的JSON數(shù)據(jù)略水,或者下面的JSON數(shù)據(jù)价卤。你會問你自己:如何才能區(qū)分一個集合和多個對象呢?答案很簡單:你不能渊涝。這是為數(shù)不多的幾個特性之一,JSON數(shù)據(jù)表示是模棱兩可的慎璧。看看下面的列子:

{
  "1$": {
    "amount": 1,
    "currency": "Dollar"
  },
  "2$": {
    "amount": 2,
    "currency": "Dollar"
  },
  "3€": {
    "amount": 3,
    "currency": "Euro"
  }
}

在JSON中跨释,讀者可以假設(shè)有名字分別是1$炸卑、2$3€的3個對象,每個對象都有自己的值煤傍。但另一方面也能被看作是一個簡單的Map盖文,1$2$3€是鍵(Key)蚯姆。

沒有可靠的方法評估一個JSON數(shù)據(jù)類型是什么五续。這里提供一些關(guān)鍵點來幫助你:

  • 第一且最重要的:上下文知識!如果你有文檔或已經(jīng)知道所描述的對象應(yīng)該是怎樣的斑粱,你應(yīng)該能夠區(qū)分單獨的對象和Map數(shù)據(jù)割卖。
  • 值的數(shù)據(jù)類型是一致的嗎?一致的就可能是Map
  • 對象名稱/鍵是動態(tài)的和廣泛的嗎?這也是Map類型的提示。

我們可以使用在列表對象文章中展示的TypeToken方法昏翰。你用我們期望的數(shù)據(jù)類型通過創(chuàng)建一個新的TypeToken得到一個Type方法:

public class AmountWithCurrency {  
    String currency;
    int amount;
}

String dollarJson = "{ '1$': { 'amount': 1, 'currency': 'Dollar'}, '2$': { 'amount': 2, 'currency': 'Dollar'}, '3€': { 'amount': 3, 'currency': 'Euro'} }";

Gson gson = new Gson();

Type amountCurrencyType =  
    new TypeToken<HashMap<String, AmountWithCurrency>>(){}.getType();

HashMap<String, AmountWithCurrency> amountCurrency =  
    gson.fromJson(dollarJson, amountCurrencyType);

amountCurrency變量實際上持有了整個正確的鍵郭毕、值集合:

嵌套的Map

Map數(shù)據(jù)結(jié)構(gòu)不會成為模型/JSON的根元素它碎。它只能是一個對象的屬性。你得用像處理列表一樣的方式序列化和反序列化它显押。我們也在這里發(fā)布了為嵌套行為的指導(dǎo)方式扳肛。

展望

本文中,你學(xué)習(xí)了如何在JSON數(shù)據(jù)和Java的Map之間序列化和反序列化乘碑。你也學(xué)習(xí)了可能遇見的問題挖息,以及如何克服的方法。下篇博客兽肤,我們會研究與Map非常相似的數(shù)據(jù)類型Set套腹。請繼續(xù)關(guān)注!

如果你需要反饋或有疑問,在評論中讓我們知道或twitter @futurestud_io

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末资铡,一起剝皮案震驚了整個濱河市电禀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笤休,老刑警劉巖尖飞,帶你破解...
    沈念sama閱讀 223,126評論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡葫松,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評論 3 400
  • 文/潘曉璐 我一進(jìn)店門底洗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腋么,“玉大人,你說我怎么就攤上這事亥揖∩豪蓿” “怎么了?”我有些...
    開封第一講書人閱讀 169,941評論 0 366
  • 文/不壞的土叔 我叫張陵费变,是天一觀的道長摧扇。 經(jīng)常有香客問我,道長挚歧,這世上最難降的妖魔是什么扛稽? 我笑而不...
    開封第一講書人閱讀 60,294評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮滑负,結(jié)果婚禮上在张,老公的妹妹穿的比我還像新娘。我一直安慰自己矮慕,他們只是感情好帮匾,可當(dāng)我...
    茶點故事閱讀 69,295評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著痴鳄,像睡著了一般瘟斜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上痪寻,一...
    開封第一講書人閱讀 52,874評論 1 314
  • 那天螺句,我揣著相機(jī)與錄音,去河邊找鬼橡类。 笑死壹蔓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猫态。 我是一名探鬼主播佣蓉,決...
    沈念sama閱讀 41,285評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼亲雪!你這毒婦竟也來了勇凭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評論 0 277
  • 序言:老撾萬榮一對情侶失蹤义辕,失蹤者是張志新(化名)和其女友劉穎虾标,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灌砖,經(jīng)...
    沈念sama閱讀 46,760評論 1 321
  • 正文 獨居荒郊野嶺守林人離奇死亡璧函,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,840評論 3 343
  • 正文 我和宋清朗相戀三年傀蚌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蘸吓。...
    茶點故事閱讀 40,973評論 1 354
  • 序言:一個原本活蹦亂跳的男人離奇死亡善炫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出库继,到底是詐尸還是另有隱情箩艺,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評論 5 351
  • 正文 年R本政府宣布宪萄,位于F島的核電站艺谆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拜英。R本人自食惡果不足惜静汤,卻給世界環(huán)境...
    茶點故事閱讀 42,315評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望居凶。 院中可真熱鬧撒妈,春花似錦、人聲如沸排监。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舆床。三九已至棋蚌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挨队,已是汗流浹背谷暮。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留盛垦,地道東北人湿弦。 一個月前我還...
    沈念sama閱讀 49,431評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像腾夯,于是被迫代替她去往敵國和親颊埃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,982評論 2 361

推薦閱讀更多精彩內(nèi)容