如何将含复合类型键的JSON字符串转换为HashMap
复合类型键的JSON转HashMap解决方案
问题描述
我有一个由键值对组成的JSON字符串,内容如下:
[ {"id": "123", "url": "ghi"} : 2, {"id": "456", "url": "def"} : 3 ]需要将其转换为HashMap,转换后的映射为:
- 键 -
{"id": "123", "url": "ghi"},值 - 2- 键 -
{"id": "456", "url": "def"},值 - 3
核心问题在于该HashMap的键为复合类型而非简单数据类型。
实现思路与Java示例
首先要明确:标准JSON不支持对象作为键(键必须是字符串),所以原JSON属于非标准格式,需要先预处理,再结合复合键类完成转换:
- 预处理非标准JSON:把
{...}:数字的格式替换为{"key": {...}, "value": 数字}的标准JSON结构,让常规JSON库可以解析。 - 定义复合键类:创建包含
id和url的类,必须重写equals()和hashCode()方法——这是HashMap能正确识别复合键的核心。 - 解析构建HashMap:遍历预处理后的JSON数组,将每个
key部分实例化为复合键对象,与value配对存入HashMap。
代码示例
复合键类定义
import java.util.Objects; public class CompositeKey { private String id; private String url; public CompositeKey(String id, String url) { this.id = id; this.url = url; } // 省略getter、setter @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; CompositeKey that = (CompositeKey) o; return Objects.equals(id, that.id) && Objects.equals(url, that.url); } @Override public int hashCode() { return Objects.hash(id, url); } @Override public String toString() { return "{\"id\": \"" + id + "\", \"url\": \"" + url + "\"}"; } }
解析转换代码
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.HashMap; import java.util.Map; public class JsonToHashMap { public static void main(String[] args) throws Exception { String nonStandardJson = "[ {\"id\": \"123\", \"url\": \"ghi\"} : 2, {\"id\": \"456\", \"url\": \"def\"} : 3 ]"; // 预处理为标准JSON String standardJson = nonStandardJson.replaceAll("(\\{[^}]+\\})\\s*:\\s*(\\d+)", "{\"key\": $1, \"value\": $2}"); ObjectMapper mapper = new ObjectMapper(); JsonNode jsonArray = mapper.readTree(standardJson); HashMap<CompositeKey, Integer> resultMap = new HashMap<>(); for (JsonNode node : jsonArray) { JsonNode keyNode = node.get("key"); CompositeKey key = new CompositeKey(keyNode.get("id").asText(), keyNode.get("url").asText()); int value = node.get("value").asInt(); resultMap.put(key, value); } // 验证输出 for (Map.Entry<CompositeKey, Integer> entry : resultMap.entrySet()) { System.out.println("键 - " + entry.getKey() + ",值 - " + entry.getValue()); } } }
关键注意事项
- 必须重写equals和hashCode:HashMap依赖这两个方法判断键的唯一性,不重写会导致无法正确存储或查找键值对。
- 非标准JSON预处理:原JSON不符合JSON规范,必须转换为标准格式才能用常规库解析。
内容的提问来源于stack exchange,提问作者Tanya Bhandari
相关产品推荐
相关产品推荐

