如何使用ArrayList创建带行列值的泛型Matrix对象?
嘿,针对你要实现泛型Matrix的需求,我来分享几个更高效简洁的方案,顺便帮你优化下之前的思路~
更优的泛型Matrix实现方案
你之前用多个ArrayList分别维护行和列的思路,会带来数据冗余和同步一致性问题(修改元素时要同时更新行、列两个集合),而且扩容逻辑会加倍复杂。下面是两种更合理的实现方式:
方案一:二维ArrayList存储(行优先,推荐大多数场景)
用一个嵌套的ArrayList<ArrayList<T>>来存储矩阵,外层List代表行,内层List代表每行的元素。列的数量可以通过配置变量维护,或者从第一行的长度获取(空矩阵场景建议单独维护cols变量)。动态扩容的逻辑集中在setValue方法里,代码更简洁易维护。
import java.util.ArrayList; import java.util.List; public class Matrix<T> { private int rows; private int cols; private List<List<T>> data; // 初始化指定行列数的空矩阵 public Matrix(int rows, int cols) { this.rows = rows; this.cols = cols; this.data = new ArrayList<>(); // 初始化每行的空元素 for (int i = 0; i < rows; i++) { ArrayList<T> rowList = new ArrayList<>(cols); for (int j = 0; j < cols; j++) { rowList.add(null); // 若为基本类型包装类,可替换为默认值如0、false等 } data.add(rowList); } } // 设置指定位置的值,自动处理行列扩容 public void setValue(int row, int col, T value) { // 处理行扩容:如果指定行超出当前行数,新增空行 if (row >= rows) { for (int i = rows; i <= row; i++) { ArrayList<T> newRow = new ArrayList<>(cols); for (int j = 0; j < cols; j++) { newRow.add(null); } data.add(newRow); } rows = row + 1; } // 处理列扩容:如果指定列超出当前列数,给所有行新增空列 if (col >= cols) { for (List<T> rowList : data) { for (int j = cols; j <= col; j++) { rowList.add(null); } } cols = col + 1; } data.get(row).set(col, value); } // 获取指定位置的值 public T getValue(int row, int col) { if (row >= rows || col >= cols) { return null; // 也可抛出IndexOutOfBoundsException,根据业务需求选择 } return data.get(row).get(col); } // 按需获取某一列的所有元素(无需提前存储) public List<T> getColumn(int col) { List<T> column = new ArrayList<>(); if (col >= cols) return column; for (List<T> rowList : data) { column.add(rowList.get(col)); } return column; } // 打印矩阵 public void printMatrix() { for (List<T> row : data) { for (T val : row) { System.out.print(val + " "); } System.out.println(); } } // 测试示例 public static void main(String[] args) { // 整数矩阵测试 Matrix<Integer> intMatrix = new Matrix<>(2, 3); intMatrix.setValue(0, 0, 21); intMatrix.setValue(0, 1, 703); intMatrix.setValue(0, 2, 22); intMatrix.setValue(1, 0, 23); intMatrix.setValue(1, 1, 3); intMatrix.setValue(1, 2, 3); intMatrix.setValue(2, 0, 13); // 自动扩容行 intMatrix.setValue(2, 1, 13); intMatrix.setValue(2, 2, 6); intMatrix.printMatrix(); // 字符串矩阵测试 Matrix<String> strMatrix = new Matrix<>(3, 3); strMatrix.setValue(0, 0, "studone"); strMatrix.setValue(0, 1, "studtwo"); strMatrix.setValue(0, 2, "studthree"); strMatrix.setValue(1, 0, "studfour"); strMatrix.setValue(1, 1, "studnine"); strMatrix.setValue(1, 2, "studten"); strMatrix.setValue(2, 0, "studran"); strMatrix.setValue(2, 1, "studmoreran"); strMatrix.setValue(2, 2, "studplus"); strMatrix.printMatrix(); } }
方案优势
- 没有数据冗余,仅维护一套存储集合
- 扩容逻辑集中,避免同步不一致问题
- 代码结构清晰,for循环仅用于初始化和扩容,没有多余操作
方案二:单一ArrayList存储(行优先,高性能场景)
如果你的矩阵规模较大、对性能要求更高,可以用单个ArrayList<T>存储,通过index = row * cols + col将二维坐标转为一维索引。这种方式减少了嵌套List的对象开销,内存连续性更好。
import java.util.ArrayList; import java.util.List; public class Matrix<T> { private int rows; private int cols; private List<T> data; public Matrix(int rows, int cols) { this.rows = rows; this.cols = cols; this.data = new ArrayList<>(rows * cols); // 初始化填充空元素 for (int i = 0; i < rows * cols; i++) { data.add(null); } } public void setValue(int row, int col, T value) { // 行扩容:新增行对应的空元素 if (row >= rows) { int newRows = row + 1; for (int i = 0; i < (newRows - rows) * cols; i++) { data.add(null); } rows = newRows; } // 列扩容:重构整个集合,给每行新增空列 if (col >= cols) { int newCols = col + 1; List<T> newData = new ArrayList<>(rows * newCols); for (int i = 0; i < rows; i++) { // 复制原有行元素 for (int j = 0; j < cols; j++) { newData.add(data.get(i * cols + j)); } // 新增空列元素 for (int j = cols; j < newCols; j++) { newData.add(null); } } data = newData; cols = newCols; } // 设置目标值 int index = row * cols + col; data.set(index, value); } public T getValue(int row, int col) { if (row >= rows || col >= cols) { return null; } return data.get(row * cols + col); } // 打印矩阵 public void printMatrix() { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { System.out.print(data.get(i * cols + j) + " "); } System.out.println(); } } }
方案优势
- 内存开销更小,访问速度更快
- 适合大规模矩阵、列扩容频率低的场景
对你原有思路的优化建议
如果你坚持要保留列的快速访问能力,也不需要单独维护列的ArrayList——可以像方案一中的getColumn方法那样,按需遍历行集合提取对应列的元素,既节省内存,又能避免行、列集合同步的问题。
内容的提问来源于stack exchange,提问作者billy
相关产品推荐
相关产品推荐

