You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何高效提取含Map与List子结构的嵌套Map指定键值对?

高效提取嵌套Map/JSON数据的优化方案

问题描述

我有一个API返回的嵌套Map(对应如下JSON结构):

{ 
  "code": 200, 
  "status_message": "OK", 
  "category_list": [ 
    { 
      "category_name": "fragile", 
      "results": [ 
        { "item_id": "001A", "item_name": "glass", "certificate_id": "A9812EJ0D7CBN12109" }, 
        { "item_id": "002A", "item_name": "porcelain", "certificate_id": "BCQ8018347503048P1" } 
      ] 
    }, 
    { 
      "category_name": "hard", 
      "results": [ 
        { "item_id": "001B", "item_name": "rock", "certificate_id": "P1024184INDHDGA831" }, 
        { "item_id": "002B", "item_name": "diamond", "certificate_id": "YDQI3910371H7D39ZX" } 
      ] 
    } 
  ] 
}

需求是仅提取fragile分类下results中的item_name与item_id,并将键名改为name和id,最终输出JSON结构如下:

{ 
  "code": 200, 
  "results": [ 
    { "id": "001A", "name": "glass" }, 
    { "id": "002A", "name": "porcelain" } 
  ] 
}

目前我用原生Java代码处理(将API结果存在Map类型的apiResult变量中),但面对更复杂的嵌套结构时,这种写法会变得繁琐,想咨询更高效的扁平化/简化处理方案。

现有实现代码

List results = ((Map) ((List) apiResult.get("category_list")).get(0)).get("results");
List finalResult = new ArrayList<>();
for(Object r : results) {
    Map inner = new HashMap();
    inner.put("name", ((Map)r).get("item_name"));
    inner.put("id", ((Map)r).get("item_id"));
    finalResult.add(inner);
}
Map result = new HashMap();
result.put("code", 200);
result.put("results", finalResult);
return result;

优化方案

1. 使用Stream API简化循环逻辑

如果你还是想用原生集合操作,Stream API可以让代码更简洁,同时避免强制类型转换的冗余,还能加入空值安全处理:

// 先过滤出category_name为fragile的分类
Optional<Map<String, Object>> fragileCategory = ((List<Map<String, Object>>) apiResult.get("category_list"))
        .stream()
        .filter(cat -> "fragile".equals(cat.get("category_name")))
        .findFirst();

if (fragileCategory.isPresent()) {
    List<Map<String, Object>> transformedResults = ((List<Map<String, Object>>) fragileCategory.get().get("results"))
            .stream()
            .map(item -> {
                Map<String, Object> newItem = new HashMap<>();
                newItem.put("id", item.get("item_id"));
                newItem.put("name", item.get("item_name"));
                return newItem;
            })
            .collect(Collectors.toList());

    Map<String, Object> finalResult = new HashMap<>();
    finalResult.put("code", apiResult.get("code")); // 复用原API的code,更灵活
    finalResult.put("results", transformedResults);
    return finalResult;
}

// 处理未找到fragile分类的情况
Map<String, Object> emptyResult = new HashMap<>();
emptyResult.put("code", 404);
emptyResult.put("results", Collections.emptyList());
return emptyResult;

这种写法比直接取索引get(0)更健壮,能应对第一个分类不是fragile的场景。

2. 自定义POJO + Jackson ObjectMapper(推荐用于复杂结构)

对于复杂嵌套结构,用POJO(普通Java对象)映射是最清晰、可维护的方案,配合Jackson库可以自动完成序列化/反序列化,彻底摆脱手动操作Map的繁琐:

首先定义对应的POJO类:

// 原API返回的顶层结构
class ApiResponse {
    private int code;
    private String status_message;
    private List<Category> category_list;

    // 生成getter、setter
    public int getCode() { return code; }
    public void setCode(int code) { this.code = code; }
    public String getStatus_message() { return status_message; }
    public void setStatus_message(String status_message) { this.status_message = status_message; }
    public List<Category> getCategory_list() { return category_list; }
    public void setCategory_list(List<Category> category_list) { this.category_list = category_list; }
}

// 分类结构
class Category {
    private String category_name;
    private List<Item> results;

    // 生成getter、setter
    public String getCategory_name() { return category_name; }
    public void setCategory_name(String category_name) { this.category_name = category_name; }
    public List<Item> getResults() { return results; }
    public void setResults(List<Item> results) { this.results = results; }
}

// 原商品项结构
class Item {
    private String item_id;
    private String item_name;
    private String certificate_id;

    // 生成getter、setter
    public String getItem_id() { return item_id; }
    public void setItem_id(String item_id) { this.item_id = item_id; }
    public String getItem_name() { return item_name; }
    public void setItem_name(String item_name) { this.item_name = item_name; }
    public String getCertificate_id() { return certificate_id; }
    public void setCertificate_id(String certificate_id) { this.certificate_id = certificate_id; }
}

// 最终输出的结构
class FinalResponse {
    private int code;
    private List<FinalItem> results;

    // 构造方法+getter、setter
    public FinalResponse(int code, List<FinalItem> results) {
        this.code = code;
        this.results = results;
    }

    public int getCode() { return code; }
    public void setCode(int code) { this.code = code; }
    public List<FinalItem> getResults() { return results; }
    public void setResults(List<FinalItem> results) { this.results = results; }
}

// 最终输出的商品项结构
class FinalItem {
    private String id;
    private String name;

    public FinalItem(String id, String name) {
        this.id = id;
        this.name = name;
    }

    // 生成getter、setter
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

然后处理逻辑会变得非常简洁:

ObjectMapper mapper = new ObjectMapper();
// 将apiResult转换为ApiResponse对象
ApiResponse response = mapper.convertValue(apiResult, ApiResponse.class);

// 找到fragile分类并转换结果
Optional<List<FinalItem>> transformedItems = response.getCategory_list().stream()
        .filter(cat -> "fragile".equals(cat.getCategory_name()))
        .findFirst()
        .map(Category::getResults)
        .map(items -> items.stream()
                .map(item -> new FinalItem(item.getItem_id(), item.getItem_name()))
                .collect(Collectors.toList()));

// 构建最终响应
FinalResponse finalResponse = new FinalResponse(
        response.getCode(),
        transformedItems.orElse(Collections.emptyList())
);

// 如果需要返回Map,再转换回去;如果直接返回JSON,用mapper.writeValueAsString(finalResponse)
return mapper.convertValue(finalResponse, Map.class);

这种方式的优势在于类型安全、可读性强,面对更复杂的嵌套结构时,只需要扩展POJO即可,维护成本极低。

3. 使用JsonPath直接提取(适合快速查询)

如果只是需要快速提取特定路径的数据,JsonPath库可以直接通过路径表达式定位目标,无需手动遍历:

// 将apiResult转换为JsonNode
JsonNode root = JsonPath.parse(apiResult).json();

// 提取fragile分类下的所有商品项
List<Map<String, Object>> fragileResults = JsonPath.read(root, "$.category_list[?(@.category_name == 'fragile')].results[*]");

// 转换键名
List<Map<String, Object>> transformedResults = fragileResults.stream()
        .map(item -> {
            Map<String, Object> newItem = new HashMap<>();
            newItem.put("id", item.get("item_id"));
            newItem.put("name", item.get("item_name"));
            return newItem;
        })
        .collect(Collectors.toList());

// 构建最终结果
Map<String, Object> finalResult = new HashMap<>();
finalResult.put("code", JsonPath.read(root, "$.code"));
finalResult.put("results", transformedResults);
return finalResult;

JsonPath的路径表达式$.category_list[?(@.category_name == 'fragile')].results[*]可以直接定位到目标数据,非常适合临时需求或结构不固定的场景。


内容的提问来源于stack exchange,提问作者Dhana D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:53:47