java二维数组矩阵相乘必须满足第一个矩阵列数等于第二个矩阵行数,结果维度为行×列,通过i(行)、j(列)、k(累加)三层循环实现行×列点积,索引错位或缺维校验将导致错误。

Java 中二维数组矩阵相乘必须严格遵循线性代数定义,核心是“行×列点积”,不是逐元素相乘。实现的关键不在技巧,而在三层索引逻辑的准确对应:外层定结果行、中层定结果列、内层遍历公共维度求和。写错一层索引,结果就全错。
矩阵乘法的维度前提与初始化
两个矩阵能相乘,前提是第一个矩阵的列数等于第二个矩阵的行数。比如 A 是 3×4,B 是 4×2,结果 C 就是 3×2。不满足就直接抛异常,而不是硬算——这是健壮性的第一道防线。
- 用 m1.length 得 A 的行数(即 C 的行数)
- 用 m1[0].length 得 A 的列数(也等于 B 的行数)
- 用 m2[0].length 得 B 的列数(即 C 的列数)
- 结果数组声明为 new double[rows1][cols2],别靠猜或写死数字
三重循环的职责必须分明
每一层循环只干一件事,命名要直白:i 负责行、j 负责列、k 负责累加下标。混淆任意两个变量,比如把 k 写成 j 或漏掉 k 层,都会导致只算对角线或越界。
- 外层 i:遍历结果矩阵的每一行(0 到 rows1−1)
- 中层 j:遍历结果矩阵的每一列(0 到 cols2−1)
- 内层 k:从 0 到 cols1−1(即公共维度长度),计算 m1[i][k] * m2[k][j] 并累加
- 内层必须初始化 sum = 0.0 或直接赋初值,不能依赖默认值侥幸
常见错误与规避方式
很多代码看似跑通却输出全零或对角阵,问题几乎都出在索引映射上。典型错误是把 m1[i][k] * m2[k][j] 写成 m1[i][j] * m2[i][j] 或 m1[j][k] * m2[k][i]——这根本不是矩阵乘法,只是乱配。
- 别用模糊名如 fila、col1,统一用 i/j/k 或 row/col/k
- 别省略维度校验:空数组、null、列≠行,都要提前拦住
- 打印调试时,别只看最终结果;可临时加 System.out.printf("C[%d][%d] = %.1f%n", i, j, sum); 验证单个元素计算是否正确
基础版够用,进阶优化有方向
标准三重循环时间复杂度 O(m·n·p),对中小规模矩阵完全够用。真遇到大矩阵,再考虑升级路径:
- 缓存友好改写:把最内层循环放在 j 上(即改变循环顺序为 i→k→j),提升 CPU 缓存命中率
- 并行化:用 ForkJoinPool 或 parallelStream 拆分行计算,注意线程安全
- 分块乘法:适合超大矩阵,把矩阵切块后局部计算,减少内存抖动
- 业务场景若频繁调用,建议封装成 Matrix 类,提供 multiply、print、transpose 等方法
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











