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

Java如何拆分嵌套列表的子元素,生成保留父字段的多条独立对象列表?

实现方案

核心逻辑是遍历所有原始员工对象,再遍历每个员工的地址列表,为每个地址生成一个独立的员工副本,副本保留原员工除地址外的所有字段,地址列表仅保留当前遍历到的单个地址。


方式1:基于实体类转换(Java 8+ 流实现)

首先定义对应实体类(示例用Lombok简化getter/setter、构造方法,无Lombok自行补充对应方法即可):

import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;

@Data
@AllArgsConstructor
public class Address {
    private String line1;
    private String line2;
    private String town;
    private String city;
    private String zipCode;
    // 可根据实际JSON字段调整属性名,比如补充state字段
}

@Data
@AllArgsConstructor
public class Employee {
    private Integer id;
    private String name;
    private String lname;
    private List<Address> address;
}

核心转换方法:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class EmployeeSplitUtil {
    public static List<Employee> splitByAddress(List<Employee> originalEmployees) {
        return originalEmployees.stream()
                .flatMap(emp -> emp.getAddress().stream()
                        .map(singleAddr -> {
                            List<Address> singleAddrList = new ArrayList<>();
                            // 若需深拷贝避免修改影响原数据,可替换为 new Address(xxx) 复制所有属性
                            singleAddrList.add(singleAddr);
                            // 复制原员工所有非地址字段
                            return new Employee(emp.getId(), emp.getName(), emp.getLname(), singleAddrList);
                        })
                )
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {
        // 测试用例
        List<Address> addresses = new ArrayList<>();
        addresses.add(new Address("Address 1 Line 1", "Address 1 Line 2", "Address 1  town", "Address 1 city", "12345"));
        addresses.add(new Address("Address 2 Line 1", "Address 2 Line 2", "Address 2 town", "Address 2 city", "22222"));
        addresses.add(new Address("Address 3 Line 1", "Address 3 Line 2", "Address 3 town", "Address 3 city", "33333"));
        Employee employee1 = new Employee(100, "adnan", "ahmed", addresses);

        List<Employee> originList = new ArrayList<>();
        originList.add(employee1);

        // 执行转换
        List<Employee> result = splitByAddress(originList);
        // 用Jackson/Gson序列化result即可得到目标JSON
    }
}

方式2:直接操作JSON节点(Jackson为例)

如果不需要转实体类,可直接操作JSON结构完成转换:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class JsonSplitUtil {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        // 假设originJson是你的原始JSON字符串
        String originJson = "{\"employee\":[{\"name\":\"adnan\",\"lname\":\"ahmed\",\"address\":[{\"state\":\"a\",\"city\":\"b\"},{\"state\":\"c\",\"city\":\"d\"}]}]}";
        JsonNode root = mapper.readTree(originJson);
        ArrayNode originEmpArray = (ArrayNode) root.get("employee");
        ArrayNode resultEmpArray = mapper.createArrayNode();

        for (JsonNode empNode : originEmpArray) {
            ArrayNode addrArray = (ArrayNode) empNode.get("address");
            for (JsonNode addr : addrArray) {
                // 复制原员工节点所有属性
                ObjectNode newEmpNode = empNode.deepCopy();
                // 替换为仅含单个地址的数组
                ArrayNode singleAddrArray = mapper.createArrayNode();
                singleAddrArray.add(addr);
                newEmpNode.set("address", singleAddrArray);
                resultEmpArray.add(newEmpNode);
            }
        }

        // 输出结果
        ((ObjectNode) root).set("employee", resultEmpArray);
        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root));
    }
}

注意事项

  • 若实体类有更多自定义字段,构造新员工对象时需全部复制,避免字段丢失
  • 若需对地址做深拷贝,可自行复制Address的所有属性生成新对象,避免后续修改影响原始数据

内容的提问来源于stack exchange,提问作者adnan ahmed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:30:05