Java不规则二维数组本质是一维数组的数组,每行长度独立、可为null或空数组;应按需分配行列、安全访问(三步校验)、动态扩容(优先List嵌套),并依问题本征形状建模。

Java 中不规则二维数组(又称“锯齿数组”)本质是 一维数组的数组,每行长度独立、可为 null 或空数组。处理其动态维度,关键不是强行统一结构,而是让数据结构随业务逻辑自然伸缩——行数和列数都按需分配、按需检查、按需扩容。
按需分配行与列:初始化阶段就拒绝“一刀切”
声明时不预设列长,只定行数;每行在真正需要时才分配具体容量:
- 用
int[][] arr = new int[n][];声明 n 行,各行初始为null - 根据实际数据填充节奏,逐行初始化:
arr[i] = new int[actualSize]; - 若某行确定无数据,建议显式设为
new int[0]而非留null,避免后续遍历反复判空
安全访问:每次取 length 或下标前,先确认“它存在且有长度”
不规则数组最常见错误就是假设 arr[i][j] 安全——其实要分三步校验:
- 外层索引合法:
i >= 0 && i < arr.length - 该行非空:
arr[i] != null - 列索引在该行范围内:
j >= 0 && j < arr[i].length
遍历时务必用 arr[i].length 作内层上限,绝不能硬写 arr[0].length 或固定数值。
立即学习“Java免费学习笔记(深入)”;
动态扩容:优先用 List<List<T>>,原生数组扩容需分步操作
频繁增删或长度高度不确定时,List<List<T>> 是更稳健的选择:
- 外层
add()即新增一行,remove()即删行 - 每行是独立
ArrayList,add()自动扩容,无需手动复制数组 - 访问前只需判断
i < list.size()和j < list.get(i).size(),语义清晰、无 null 风险
若必须用原生二维数组(如性能敏感场景),扩容需两步分离:
- 扩行数:用
Arrays.copyOf(arr, newRowCount) - 扩某行:先判
arr[i] != null,再arr[i] = Arrays.copyOf(arr[i], newColCount)
算法建模:让结构贴合问题本征形状
不规则数组的价值,在于它天然适配现实中的非对称数据形态:
-
杨辉三角:第 i 行有 i+1 个元素 →
triangle[i] = new int[i + 1] - 树的层序结果:每层节点数不定 → 先 BFS 统计每层数量,再逐行分配长度填值
-
稀疏矩阵/关系表:只存有效项 → 每行存
[colIndex, value]对,长度即非零元个数 -
DP 状态压缩:如单词拆分 II 中
dp[i]存所有解 → 行长由回溯路径数量决定,无法预估
这些场景下,强行用规则数组不仅浪费空间,还会让边界逻辑复杂化。不规则结构反而是最简洁、最真实的表达。


















