Gson 对 Map 结构进行映射
我们将在本篇文章中探讨如何使用 Java Map。 我们将学习如何使用 Gson 库(反)序列化 Java Map。
Java Map 的序列化
Java Map是一种非常灵活的数据类型,可用于各种场景。 它使我们的开发人员能够在 Java 编程语言中实现许多现实世界的情况。 由于 Java Map的使用范围如此之广,因此我们可能不会涵盖确切的用例,但该方法适用于所有这些用例。
让我们从应用具有员工姓名列表的场景开始。 我们被要求实施一个视图以显示以特定首字母开头的所有员工。 例如,用户可以选择字母 A,我们的应用程序将返回三个匹配的员工 Andreas、Aden 和 Arnold。 第一次迭代只是一个包含所有名称的列表,但性能还不够好。 因此,实现被切换到 HashMap
,其中键是第一个字母(即 A),值是名称列表。
如果我们创建我们的 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 = new Gson();
String employeeJson = gson.toJson(employees);
这将会生成如下的JSON
{
"M": [
"Marcus",
"Mary"
],
"C": [
"Christian",
"Carter"
],
"A": [
"Andreas",
"Arnold",
"Aden"
]
}
每个键(A、C 和 M)都有一个名称列表,这正是我们想要描述的。
Java Map 的反序列化
如果我们查看上一节的结果 JSON 或下面的 JSON,则会问自己:如何发现集合和多个对象之间的区别? 简单的答案是:你不能。 这是 JSON 数据表示不明确的少数情况之一。 让我们看下面的例子:
{
"1$": {
"amount": 1,
"currency": "Dollar"
},
"2$": {
"amount": 2,
"currency": "Dollar"
},
"3€": {
"amount": 3,
"currency": "Euro"
}
}
这是 JSON,大家可以假设存在三个名称为 1$ 、2$ 和 3€ 的对象。 这些对象中的每一个都有一些值。 但另一方面,它也可以是一个简单的 Map,其中 1$ 、2$ 和 3€ 是键。
没有万无一失的方法来评估 JSON 是什么数据类型。 一些可以帮助大家的建议是:
- 首先也是最重要的:上下文知识! 如果有文档或知道对象所描述的内容,我们应该能够解释是否存在单独的对象或数据映射。
- 值的数据类型是否一致? 然后它向 Map 提示。
- 对象名称/键是否动态且范围广泛?
- 我们已经在之前的文章中向大家展示了如何映射常规对象,因此在本篇文章中,我们将假设 JSON 是数据映射。 我们如何将上面显示的 JSON 映射到 Java 对象?
我们可以使用我们在 List of Objects 文章中向大家展示的相同 TypeToken 方法。 我们可以通过使用我们预期的数据类型创建一个新的 TypeToken 来创建一个适当的类型:
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 数据结构不必是 模型/JSON 的根元素。 它可以只是一个对象的属性。 我们可以像使用列表一样(反)序列化它。 我们已经在这里发布了嵌套对象映射指南。
在这篇文章中,我们已经了解了如何从 JSON 序列化和反序列化 Java Map。 我们已经了解了潜在的障碍以及如何克服它们。 在下一篇文章中,我们将介绍非常相似的 Java 数据类型 Sets 的映射。