如何判断Map<String,Object>中的嵌套数组及修复失效代码
问题描述
我有一个格式为Map<String, Object>的输入数据结构,对应的JSON Schema如下:
{ "$schema": "http://json-schema.org/draft-07/schema#", "title": "Schema", "type": "object", "properties": { "uniqueTxnId": { "type": "string" }, "countryCode": { "type": "string" }, "url": { "type": "string" }, "reference": { "type": "string" }, "reason": { "type": "string" }, "audit": [ { "docType": "", "date": "", "status": "", "reason": "", "remarks": "" }, { "docType": "", "date": "", "status": "", "reason": "", "remarks": "" } ] } }
我希望通用判断该结构中是否存在数组类型的值(避免硬编码键),以便遍历列表获取值。目前尝试的代码如下,但无法正常工作:
for (Map.Entry<String, Object> entry : input.entrySet()) { if(entry.getValue() instanceof JSONArray && entry.getValue().toString().startsWith("[")) { List<Object> list = (List<Object>) entry.getValue(); embeddedArrayObjectSize = list.size(); System.out.println("Get first element " + list.get(0)); System.out.println("List of elements " + list); System.out.println(entry.getKey()); } }
解决方案
你的代码存在两个核心问题:
- 类型判断错误:如果
Map由Jackson、Gson这类常用JSON解析库生成,数组类型通常会被解析为List实现类,而非JSONArray(这是org.json库的专属类型),用instanceof JSONArray会漏判绝大多数情况。 - 冗余的字符串校验:
instanceof已经能完成类型判断,额外的toString().startsWith("[")完全没必要,还可能因部分集合的toString格式差异导致误判。
修改后的通用判断代码如下:
for (Map.Entry<String, Object> entry : input.entrySet()) { Object value = entry.getValue(); // 直接判断是否为List类型,覆盖所有数组/列表的解析结果 if (value instanceof List) { List<Object> list = (List<Object>) value; int embeddedArrayObjectSize = list.size(); System.out.println("数组键名:" + entry.getKey()); System.out.println("数组长度:" + embeddedArrayObjectSize); if (!list.isEmpty()) { System.out.println("第一个元素:" + list.get(0)); } System.out.println("所有元素:" + list); } }
适配org.json库的额外处理
如果你的Map是由org.json库生成(值可能为JSONArray),可以补充类型判断并统一转为List处理:
for (Map.Entry<String, Object> entry : input.entrySet()) { Object value = entry.getValue(); List<Object> list = null; if (value instanceof List) { list = (List<Object>) value; } else if (value instanceof JSONArray) { list = ((JSONArray) value).toList(); } if (list != null) { int embeddedArrayObjectSize = list.size(); System.out.println("数组键名:" + entry.getKey()); System.out.println("数组长度:" + embeddedArrayObjectSize); if (!list.isEmpty()) { System.out.println("第一个元素:" + list.get(0)); } System.out.println("所有元素:" + list); } }
该实现完全无需硬编码键名,会自动遍历所有键值对识别数组/列表类型的值。
内容的提问来源于stack exchange,提问作者Rana Sujitha
相关产品推荐
相关产品推荐

