You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:11:48