Java中可用多层for循环或动态进位法实现多维数组笛卡尔积,适用于省份×城市×年份等业务组合场景,支持生成字符串或POJO对象,兼顾效率与可维护性。

在 Java 中,用数组实现笛卡尔积(Cartesian Product)并不需要依赖集合框架或递归回溯——尤其当目标是生成“全排列式业务数据集”(即各维度字段的穷举组合)时,用多层循环配合原始数组即可高效完成,代码清晰、内存可控、无栈溢出风险。
理解业务场景中的“笛卡尔积”而非数学全排列
注意区分:业务中常说的“全排列数据集”,多数实为多个独立字段取值的交叉组合(如:省份 × 城市 × 行业 × 年份),属于笛卡尔积;而传统“全排列”(permutation)指对同一数组元素重排(如 [A,B,C] → [B,A,C], [C,B,A]…),二者逻辑不同。本文聚焦前者——即 多维数组的叉乘组合。
例如: - 省份 = ["北京", "上海"] - 城市 = ["朝阳", "浦东", "徐汇"] - 年份 = [2023, 2024] → 共 2 × 3 × 2 = 12 条组合记录
用嵌套 for 循环直接遍历(推荐:简单、零依赖、易调试)
当维度数量固定(如 3~5 个字段),直接写对应层数的 for 循环最直观。Java 数组天然支持索引访问,无需装箱拆箱:
- 定义 String[][] 或 Object[][] 存储各维度取值(每行一个维度)
- 外层循环控制第一维索引,内层依次嵌套,最内层拼接/封装一条完整记录
- 用 StringBuilder 或 String.format 拼接字符串,或 new 自定义 POJO 实例
示例(生成字符串组合):
String[] provinces = {"北京", "上海"};
String[] cities = {"朝阳", "浦东", "徐汇"};
Integer[] years = {2023, 2024};
<p>List<string> result = new ArrayList();
for (String p : provinces) {
for (String c : cities) {
for (Integer y : years) {
result.add(p + "-" + c + "-" + y);
}
}
}
// result 包含 12 条形如 "北京-朝阳-2023" 的字符串</string></p>用动态循环处理任意维度(避免硬编码层数)
若维度数不固定(如配置文件读取 N 个字段数组),可用“模拟进位”方式实现动态笛卡尔积,核心是维护一个 int[] index 表示当前各维下标,并按“类加法”递增:
- 初始化 index 全为 0,计算总组合数(各维长度乘积)
- 每次循环:按 index[i] 取各维元素 → 构建一条记录 → 对 index 末位+1 → 从右向左处理进位(超长则置 0,左邻+1)
- 直到 index 所有位均归零(即完成一轮)
关键代码片段:
String[][] dims = {provinces, cities, years}; // 动态维度数组
int[] index = new int[dims.length];
long total = Arrays.stream(dims).mapToLong(arr -> arr.length).reduce(1, (a, b) -> a * b);
<p>for (long i = 0; i </p><pre class="brush:java;toolbar:false;">// 进位逻辑(从右往左)
int pos = dims.length - 1;
while (pos >= 0) {
index[pos]++;
if (index[pos] <p>}</p>生成业务对象而非字符串(提升可维护性)
实际业务中,应封装为 POJO 而非字符串拼接。例如定义:
record BizData(String province, String city, Integer year) {}
在循环体内直接构造:
- 静态维度:new BizData(p, c, y)
- 动态维度:用反射或 switch 根据维度名赋值(更推荐用 Map
临时承载,再转 VO) - 如需去重或过滤,可在构造后调用 .filter() 或 if 判断(如跳过 "北京-徐汇-2023")
这样生成的数据集可直接用于 Excel 导出、SQL 批量插入、规则引擎输入等下游环节。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











