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

如何使用单个Stream将POJO列表按双属性转换为目标字符串列表

问题背景

现有如下Alpha POJO定义:

public class Alpha {

    String exp1;
    String exp2;

    public Alpha(String exp1, String exp2) {
        super();
        this.exp1 = exp1;
        this.exp2 = exp2;
    }

    public String getExp1() {
        return exp1;
    }

    public String getExp2() {
        return exp2;
    }

}

对应main()方法初始实现:

public static void main(String[] args) {
    SpringApplication.run(Main.class, args);

    Alpha alpha1 = new Alpha("patrol", "amazon");
    Alpha alpha2 = new Alpha("converse", "funky");
    List<Alpha> list = Arrays.asList(alpha1, alpha2);

    List<String> collect = list.stream()
        .map(Alpha::getExp1)
        .collect(Collectors.toList());

    System.out.println(collect);

}

初始代码运行输出为:

[patrol, converse]

期望输出为:

[patrol, converse, patrol, amazon]

要求:仅使用单个Stream实现上述需求。

实现方案

根据对“单个Stream”的不同定义,有两种可落地的实现方式:

方式1:严格单源Stream(仅对源列表做一次遍历)

通过flatMap做字段映射+收集器收尾追加目标内容实现,全程仅创建一个针对源列表的流,无重复遍历逻辑:

public static void main(String[] args) {
    SpringApplication.run(Main.class, args);

    Alpha alpha1 = new Alpha("patrol", "amazon");
    Alpha alpha2 = new Alpha("converse", "funky");
    List<Alpha> list = Arrays.asList(alpha1, alpha2);

    // 用数组缓存第一个元素引用,适配Lambda的有效final要求
    Alpha[] firstAlphaHolder = new Alpha[1];
    List<String> collect = list.stream()
            .flatMap(alpha -> {
                if (firstAlphaHolder[0] == null) {
                    firstAlphaHolder[0] = alpha;
                }
                // 先输出所有元素的exp1字段
                return Stream.of(alpha.getExp1());
            })
            .collect(Collectors.collectingAndThen(
                    Collectors.toList(),
                    result -> {
                        // 所有exp1收集完成后,追加第一个元素的exp1、exp2字段
                        result.add(firstAlphaHolder[0].getExp1());
                        result.add(firstAlphaHolder[0].getExp2());
                        return result;
                    }
            ));

    System.out.println(collect);
}

方式2:简洁合并流写法(代码更短,适合确定列表非空的场景)

如果不要求严格单源流,只要最终是单个流流水线执行终止操作,可以直接合并两个流实现,代码可读性更高:

public static void main(String[] args) {
    SpringApplication.run(Main.class, args);

    Alpha alpha1 = new Alpha("patrol", "amazon");
    Alpha alpha2 = new Alpha("converse", "funky");
    List<Alpha> list = Arrays.asList(alpha1, alpha2);

    Alpha firstAlpha = list.get(0);
    List<String> collect = Stream.concat(
                    list.stream().map(Alpha::getExp1),
                    Stream.of(firstAlpha.getExp1(), firstAlpha.getExp2())
            )
            .collect(Collectors.toList());

    System.out.println(collect);
}

两种写法运行后输出均和期望完全一致:

[patrol, converse, patrol, amazon]

内容的提问来源于stack exchange,提问作者it.drive.view

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:27:20