登录
首页 >  文章 >  java教程

Java8流计算笛卡尔积实战教程

时间:2026-05-27 17:21:51 183浏览 收藏

本文深入解析了如何利用 Java 8 的 Stream API 和 Lambda 表达式高效实现集合间的笛卡尔积运算,从最基础的双列表组合(如颜色×尺寸)出发,通过 flatMap + map 的经典嵌套模式构造数组、List 或自定义 DTO,逐步拓展到支持任意数量集合的通用封装方法,并结合真实业务场景(如 SKU 属性组合)演示了面向对象的优雅实现;同时直击实践痛点,提醒开发者规避空集合陷阱、基本类型流转换误区及大规模组合引发的内存溢出风险,是一篇兼具原理深度、代码实操性与工程警示价值的实用指南。

集合的笛卡尔积运算:实战利用 Java 8 流操作计算两个变量集合的组合

用 Java 8 的 Stream 和 Lambda 实现两个集合的笛卡尔积,核心在于 flatMap + map 的嵌套组合:外层流遍历第一个集合,对每个元素,内层流映射第二个集合的所有元素,生成成对结果。

基础写法:两个 List 的简单组合

适用于 ListList 等任意引用类型集合:

  • 先将第一个集合转为 stream
  • 对每个元素 a,用 flatMap 拉平第二个集合的 stream 映射结果
  • map 中构造组合对象(如数组、List 或自定义 DTO)

示例代码:

List<String> colors = Arrays.asList("红", "蓝");
List<String> sizes = Arrays.asList("S", "M", "L");

List<String[]> result = colors.stream()
    .flatMap(color -> sizes.stream()
        .map(size -> new String[]{color, size}))
    .collect(Collectors.toList());
// 结果:[["红","S"], ["红","M"], ["红","L"], ["蓝","S"], ["蓝","M"], ["蓝","L"]]

封装为通用方法:支持任意数量集合

当需要处理三个或更多集合(如颜色、尺寸、产地),可把它们放入一个 List>,再用循环 + 累积流实现:

  • 初始化结果集为第一个集合
  • 逐个与后续集合做笛卡尔积:用 stream().flatMap(...) 替换当前结果
  • 每次 map 中拼接字符串或构建新对象

关键逻辑片段:

public static <T> List<String> descartes(List<List<T>> lists) {
    List<String> result = new ArrayList<>();
    for (List<T> list : lists) {
        if (result.isEmpty()) {
            result = list.stream().map(Object::toString).collect(Collectors.toList());
        } else {
            result = result.stream()
                .flatMap(r -> list.stream().map(item -> r + " " + item))
                .collect(Collectors.toList());
        }
    }
    return result;
}

转为自定义对象:比如生成 SKU 组合 DTO

实际业务中往往不只要字符串拼接,而是要构造带字段的对象。例如两个 ID 列表生成 TagsAttributeDto

  • 定义 DTO 类,含 tagsIdattributeId 字段
  • map 中直接 new 实例并赋值
  • 确保构造过程无副作用,符合函数式风格

示例:

public static List<TagsAttributeDto> descartes(List<Long> tagsIds, List<Long> attributesIds) {
    return tagsIds.stream()
        .flatMap(tagId -> attributesIds.stream()
            .map(attrId -> new TagsAttributeDto(tagId, attrId)))
        .collect(Collectors.toList());
}

注意事项与避坑点

有些场景容易出错,需特别注意:

  • 不能直接对 int[] 调用 Arrays.stream() 后 flatMap —— 它返回的是 IntStream,需用 mapToObj 转回引用流
  • 空集合参与运算时,结果为空;若需保底(如默认值),需提前判空处理
  • 组合结果量呈乘积级增长(如 10×10×10=1000),大数据量时避免内存溢出,必要时改用分页或流式消费

本篇关于《Java8流计算笛卡尔积实战教程》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于文章的相关知识,请关注golang学习网公众号!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>