如何实现Map<int, Map<int, Map<int, Map<int, int>>>>与JSON的相互编解码?
解决多层嵌套Map与JSON的编解码问题
我来帮你搞定这个多层嵌套Map的JSON转换难题!首先得明确一个核心点:JSON的键只能是字符串类型,而你的数据结构用了多层int作为Map的键,这是转换时最容易踩坑的地方。下面我会分编码(Map转JSON)和解码(JSON转Map)两个部分,结合具体示例帮你实现。
一、编码:将嵌套Map转为JSON字符串
不管用哪种编程语言,核心思路都是让int键自动转换为字符串(符合JSON规范),同时保证嵌套结构正确序列化。这里给你两种常用语言的示例:
示例1:Java + Jackson
Jackson默认会把int类型的Map键序列化为字符串,直接用ObjectMapper就能搞定:
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Map; public class CalendarJsonConverter { public static void main(String[] args) throws Exception { // 假设你已经构造好目标嵌套Map数据 Map<Integer, Map<Integer, Map<Integer, Map<Integer, Integer>>>> calendarData = ...; ObjectMapper mapper = new ObjectMapper(); // 生成格式化的JSON字符串(方便阅读) String jsonStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(calendarData); System.out.println(jsonStr); } }
输出的JSON结构示例:
{ "2021" : { "1" : { "4" : { "2" : 3 }, "5" : { "2" : 3 } } }, "2022" : { "1" : { "4" : { "2" : 3 } } } }
示例2:Dart + dart:convert
Dart的jsonEncode工具默认也会处理int键转字符串,直接调用即可:
import 'dart:convert'; void main() { Map<int, Map<int, Map<int, Map<int, int>>>> calendarData = { 2021: { 1: { 4: {2: 3}, 5: {2: 3}, } }, 2022: { 1: { 4: {2: 3}, } } }; String jsonStr = jsonEncode(calendarData); print(jsonStr); }
二、解码:将JSON字符串转回嵌套Map
这里的关键是把JSON中的字符串键转回int类型——默认反序列化会得到Map<String, ...>结构,需要手动遍历转换每一层的键。
示例1:Java + Jackson
你可以手动遍历转换,或者自定义反序列化器,这里先给最直观的手动转换方式:
import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; public class CalendarJsonConverter { public static void main(String[] args) throws Exception { String jsonStr = "..."; // 你的JSON字符串 ObjectMapper mapper = new ObjectMapper(); // 先反序列化为字符串键的多层Map Map<String, Map<String, Map<String, Map<String, Integer>>>> strKeyMap = mapper.readValue(jsonStr, Map.class); // 转换为int键的目标Map Map<Integer, Map<Integer, Map<Integer, Map<Integer, Integer>>>> intKeyMap = new HashMap<>(); for (Map.Entry<String, Map<String, Map<String, Map<String, Integer>>>> yearEntry : strKeyMap.entrySet()) { int year = Integer.parseInt(yearEntry.getKey()); Map<String, Map<String, Map<String, Integer>>> weekStrMap = yearEntry.getValue(); Map<Integer, Map<Integer, Map<Integer, Integer>>> weekIntMap = new HashMap<>(); for (Map.Entry<String, Map<String, Map<String, Integer>>> weekEntry : weekStrMap.entrySet()) { int week = Integer.parseInt(weekEntry.getKey()); Map<String, Map<String, Integer>> dayStrMap = weekEntry.getValue(); Map<Integer, Map<Integer, Integer>> dayIntMap = new HashMap<>(); for (Map.Entry<String, Map<String, Integer>> dayEntry : dayStrMap.entrySet()) { int day = Integer.parseInt(dayEntry.getKey()); Map<String, Integer> dataStrMap = dayEntry.getValue(); Map<Integer, Integer> dataIntMap = new HashMap<>(); for (Map.Entry<String, Integer> dataEntry : dataStrMap.entrySet()) { int key = Integer.parseInt(dataEntry.getKey()); dataIntMap.put(key, dataEntry.getValue()); } dayIntMap.put(day, dataIntMap); } weekIntMap.put(week, dayIntMap); } intKeyMap.put(year, weekIntMap); } // 现在intKeyMap就是你需要的原始结构了 } }
示例2:Dart + dart:convert
Dart中可以写一个转换函数,遍历每一层把字符串键转成int:
import 'dart:convert'; Map<int, Map<int, Map<int, Map<int, int>>>> convertJsonToIntMap(Map<String, dynamic> json) { Map<int, Map<int, Map<int, Map<int, int>>>> result = {}; json.forEach((yearStr, weekMap) { int year = int.parse(yearStr); Map<int, Map<int, Map<int, int>>> weekIntMap = {}; (weekMap as Map<String, dynamic>).forEach((weekStr, dayMap) { int week = int.parse(weekStr); Map<int, Map<int, int>> dayIntMap = {}; (dayMap as Map<String, dynamic>).forEach((dayStr, dataMap) { int day = int.parse(dayStr); Map<int, int> dataIntMap = {}; (dataMap as Map<String, dynamic>).forEach((keyStr, value) { int key = int.parse(keyStr); dataIntMap[key] = value; }); dayIntMap[day] = dataIntMap; }); weekIntMap[week] = dayIntMap; }); result[year] = weekIntMap; }); return result; } void main() { String jsonStr = '{"2021":{"1":{"4":{"2":3},"5":{"2":3}}},"2022":{"1":{"4":{"2":3}}}}'; Map<String, dynamic> jsonMap = jsonDecode(jsonStr); var calendarData = convertJsonToIntMap(jsonMap); print(calendarData); }
关键注意事项
- JSON键的类型限制:永远记住JSON不支持非字符串的键,所以序列化时int键一定会转成字符串,反序列化必须手动转回来。
- 嵌套层级处理:如果嵌套层数固定,手动遍历最直接;如果层数不固定,可以写递归函数来简化代码,避免重复逻辑。
- 异常处理:转换键的时候要捕获格式异常(比如Java的
NumberFormatException、Dart的FormatException),防止JSON中出现非数字的键导致程序崩溃。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

