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

Java按id分组将List<Object[]>转为List<MyBean>的Stream实现

Stream 实现方案

直接用Collectors.toMap完成分组聚合即可,不需要先生成分组的中间List,全程流式处理,也不需要给MyBean额外添加setter、无参构造,完全适配你最初定义的带Builder的类结构:

import java.util.*;
import java.util.stream.Collectors;

public class TestClass {
    public static void main(String[] args) {
        TestClass test = new TestClass();
        List<Object[]> resultList = test.buildResultList();

        List<MyBean> beans = new ArrayList<>(resultList.stream()
                .collect(Collectors.toMap(
                        // 分组key:每行数据的id
                        arr -> (Integer) arr[0],
                        // 首次遇到某个id时,初始化MyBean对象
                        arr -> {
                            Map<String, Object> initAttrs = new HashMap<>();
                            initAttrs.put((String) arr[2], arr[3]);
                            return MyBean.builder()
                                    .id((Integer) arr[0])
                                    .name((String) arr[1])
                                    .customAttributes(initAttrs)
                                    .build();
                        },
                        // 同id的重复数据,直接把自定义属性合并到已存在的Bean中
                        (existBean, newBean) -> {
                            existBean.getCustomAttributes().putAll(newBean.getCustomAttributes());
                            return existBean;
                        },
                        // 如果需要保留id首次出现的顺序,解开下面这行注释即可
                        // LinkedHashMap::new
                )).values());

        System.out.println(beans);
    }

    private List<Object[]> buildResultList() {
        List<Object[]> resultList = new ArrayList<>();

        Object[] arr1 = new Object[4];
        arr1[0] = 1; arr1[1] = "name 1"; arr1[2] = "custom_attr_1"; arr1[3] = "custom_attr_1_val_1";
        resultList.add(arr1);

        Object[] arr2 = new Object[4];
        arr2[0] = 1; arr2[1] = "name 1"; arr2[2] = "custom_attr_2"; arr2[3] = "custom_attr_2_val_1";
        resultList.add(arr2);

        Object[] arr3 = new Object[4];
        arr3[0] = 1; arr3[1] = "name 1"; arr3[2] = "custom_attr_3"; arr3[3] = "custom_attr_3_val_1";
        resultList.add(arr3);

        Object[] arr4 = new Object[4];
        arr4[0] = 2; arr4[1] = "name 2"; arr4[2] = "custom_attr_1"; arr4[3] = "custom_attr_1_val_2";
        resultList.add(arr4);

        Object[] arr5 = new Object[4];
        arr5[0] = 2; arr5[1] = "name 2"; arr5[2] = "custom_attr_2"; arr5[3] = "custom_attr_2_val_2";
        resultList.add(arr5);

        Object[] arr6 = new Object[4];
        arr6[0] = 2; arr6[1] = "name 2"; arr6[2] = "custom_attr_3"; arr6[3] = "custom_attr_3_val_2";
        resultList.add(arr6);

        Object[] arr7 = new Object[4];
        arr7[0] = 3; arr7[1] = "name 3"; arr7[2] = "custom_attr_1"; arr7[3] = "custom_attr_1_val_3";
        resultList.add(arr7);

        Object[] arr8 = new Object[4];
        arr8[0] = 3; arr8[1] = "name 3"; arr8[2] = "custom_attr_2"; arr8[3] = "custom_attr_2_val_3";
        resultList.add(arr8);

        Object[] arr9 = new Object[4];
        arr9[0] = 3; arr9[1] = "name 3"; arr9[2] = "custom_attr_3"; arr9[3] = "custom_attr_3_val_3";
        resultList.add(arr9);

        return resultList;
    }
}

// 保留原MyBean定义即可,不需要额外加@Setter、@NoArgsConstructor
@Getter
@ToString
@Builder(toBuilder = true)
class MyBean {
    private Integer id;
    private String name;
    private Map<String, Object> customAttributes;

    // equals和hashCode方法基于id字段实现
}
方案对比原实现的优势
  • 少了一次中间分组生成Map<Integer, List<Object[]>>的过程,一次流收集就完成分组、对象构造、属性合并全流程,内存占用更低。
  • 不需要修改原MyBean的类结构,不用强制添加setter、无参构造,不会破坏类的封装性。
  • 去掉了循环内重复给name、customAttributes字段赋值的无效逻辑,合并属性直接复用Map的putAll方法,代码更简洁。

提示:如果使用JDK9及以上版本,初始化自定义属性可以直接用Map.of((String) arr[2], arr[3])替换逐行put的写法,代码会更精简。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:36:25