杰瑞科技汇

Java二维ArrayList如何初始化与使用?

什么是二维 ArrayList

在 Java 中,标准的 ArrayList 是一个一维的、可以动态增长的对象列表,一个“二维 ArrayList”本质上是一个 ArrayList,它的每一个元素又是一个 ArrayList

Java二维ArrayList如何初始化与使用?-图1
(图片来源网络,侵删)

你可以把它想象成一个“数组的数组”,但它的每一行(内部的 ArrayList)都可以拥有不同的长度,并且可以动态地增加或删除行和列,这比传统的二维数组(int[][])更加灵活。


如何声明和初始化二维 ArrayList

基本语法

// 声明一个外部的 ArrayList,它内部的元素是另一个 ArrayList
// 我们会指定内部的 ArrayList 存储的数据类型,Integer, String 等
ArrayList<ArrayList<String>> twoDArrayList;
// 初始化
twoDArrayList = new ArrayList<ArrayList<String>>();

完整的初始化示例

一个更完整的初始化过程,通常包括创建内部的 ArrayList 并添加到外部的 ArrayList 中。

import java.util.ArrayList;
public class TwoDArrayListExample {
    public static void main(String[] args) {
        // 1. 声明并初始化外部的 ArrayList
        ArrayList<ArrayList<Integer>> matrix = new ArrayList<>();
        // 2. 创建并添加第一行 (内部 ArrayList)
        ArrayList<Integer> row1 = new ArrayList<>();
        row1.add(1);
        row1.add(2);
        row1.add(3);
        matrix.add(row1);
        // 3. 创建并添加第二行
        ArrayList<Integer> row2 = new ArrayList<>();
        row2.add(4);
        row2.add(5);
        matrix.add(row2);
        // 4. 创建并添加第三行
        ArrayList<Integer> row3 = new ArrayList<>();
        row3.add(6);
        row3.add(7);
        row3.add(8);
        row3.add(9); // 这一行的长度比前两行长
        matrix.add(row3);
        // matrix 看起来像这样:
        // [ [1, 2, 3],
        //   [4, 5],
        //   [6, 7, 8, 9] ]
        System.out.println("完整的二维 ArrayList: " + matrix);
    }
}

使用循环初始化(更优雅的方式)

我们可以使用循环来简化初始化过程,特别是当所有行的初始长度相同时。

import java.util.ArrayList;
public class TwoDArrayListInitialization {
    public static void main(String[] args) {
        int rows = 3;
        int cols = 4;
        ArrayList<ArrayList<String>> grid = new ArrayList<>();
        for (int i = 0; i < rows; i++) {
            // 为每一行创建一个新的 ArrayList
            ArrayList<String> currentRow = new ArrayList<>();
            for (int j = 0; j < cols; j++) {
                // 向当前行添加元素
                currentRow.add("Cell-" + i + "-" + j);
            }
            // 将当前行添加到外部的 ArrayList 中
            grid.add(currentRow);
        }
        System.out.println("使用循环初始化的网格: " + grid);
        // 输出: [[Cell-0-0, Cell-0-1, Cell-0-2, Cell-0-3], [Cell-1-0, ...], ...]
    }
}

如何访问和修改元素

访问二维 ArrayList 的元素需要使用两次 get() 方法:第一次获取行,第二次获取该行中的列。

Java二维ArrayList如何初始化与使用?-图2
(图片来源网络,侵删)
import java.util.ArrayList;
public class AccessElements {
    public static void main(String[] args) {
        ArrayList<ArrayList<String>> data = new ArrayList<>();
        data.add(new ArrayList<>(List.of("A", "B", "C")));
        data.add(new ArrayList<>(List.of("D", "E")));
        // --- 访问元素 ---
        // 获取第 1 行 (索引 0)
        ArrayList<String> firstRow = data.get(0);
        System.out.println("第一行: " + firstRow); // 输出: [A, B, C]
        // 获取第 1 行的第 2 个元素 (索引 1)
        String element = data.get(0).get(1);
        System.out.println("第1行第2个元素是: " + element); // 输出: B
        // --- 修改元素 ---
        // 修改第 2 行 (索引 1) 的第 1 个元素 (索引 0)
        data.get(1).set(0, "Z");
        System.out.println("修改后的数据: " + data); // 输出: [[A, B, C], [Z, E]]
    }
}

如何添加和删除行/列

添加行

直接使用外层 ArrayListadd() 方法即可。

// 假设 data 已经存在
ArrayList<String> newRow = new ArrayList<>();
newRow.add("X");
newRow.add("Y");
data.add(newRow); // 在末尾添加一行
data.add(0, newRow); // 在开头(索引0)插入一行

删除行

同样使用外层 ArrayListremove() 方法。

// 假设 data 已经存在
data.remove(1); // 删除索引为 1 的那一行

添加列

“添加列”意味着要遍历每一行,然后在每一行的末尾(或指定位置)添加一个新元素。

// 假设 data 是 [[A, B, C], [D, E]]
String newColumnValue = "New";
for (ArrayList<String> row : data) {
    row.add(newColumnValue); // 在每一行的末尾添加 "New"
}
// data 变成 [[A, B, C, New], [D, E, New]]

删除列

“删除列”同样需要遍历每一行,然后从每一行中删除指定索引的元素。

Java二维ArrayList如何初始化与使用?-图3
(图片来源网络,侵删)
// 假设 data 是 [[A, B, C, New], [D, E, New]]
int columnIndexToRemove = 0; // 删除第 1 列
for (ArrayList<String> row : data) {
    // 检查该行是否有足够的列,避免 IndexOutOfBoundsException
    if (row.size() > columnIndexToRemove) {
        row.remove(columnIndexToRemove);
    }
}
// data 变成 [[B, C, New], [E, New]]

完整示例代码

这是一个综合了所有操作的完整示例。

import java.util.ArrayList;
import java.util.List;
public class TwoDArrayListOperations {
    public static void main(String[] args) {
        // 1. 初始化
        ArrayList<ArrayList<String>> table = new ArrayList<>();
        table.add(new ArrayList<>(List.of("Name", "Age", "City")));
        table.add(new ArrayList<>(List.of("Alice", "30", "New York")));
        table.add(new ArrayList<>(List.of("Bob", "24", "London")));
        System.out.println("--- 初始表格 ---");
        printTable(table);
        // 2. 添加一行
        ArrayList<String> newRow = new ArrayList<>(List.of("Charlie", "35", "Paris"));
        table.add(newRow);
        System.out.println("\n--- 添加新行后 ---");
        printTable(table);
        // 3. 修改一个元素
        table.get(1).set(1, "31"); // Alice 的年龄从 30 改为 31
        System.out.println("\n--- 修改年龄后 ---");
        printTable(table);
        // 4. 添加一列(国家)
        System.out.println("\n--- 添加“国家”列 ---");
        for (ArrayList<String> row : table) {
            if (row == table.get(0)) {
                row.add("Country"); // 添加表头
            } else {
                row.add("USA"); // 为其他行添加数据
            }
        }
        printTable(table);
        // 5. 删除一列(年龄)
        System.out.println("\n--- 删除“年龄”列 ---");
        for (ArrayList<String> row : table) {
            row.remove(1); // 年龄列在索引 1
        }
        printTable(table);
        // 6. 删除一行
        table.remove(2); // 删除 Bob 的那一行
        System.out.println("\n--- 删除 Bob 的行后 ---");
        printTable(table);
    }
    // 辅助方法:用于美观地打印表格
    public static void printTable(ArrayList<ArrayList<String>> table) {
        for (ArrayList<String> row : table) {
            System.out.println(row);
        }
    }
}

二维 ArrayList vs. 二维数组 (int[][])

特性 ArrayList<ArrayList<T>> (二维动态列表) T[][] (二维数组)
大小 动态,可以随时添加或删除行和列。 固定,创建时必须指定大小,改变大小需要创建新数组。
类型 可以存储任意对象类型 (Integer, String 等)。 可以存储基本类型 (int, char 等) 和对象类型。
性能 由于涉及到自动装箱/拆箱和动态扩容,访问速度相对较慢 访问速度非常快,基于连续内存地址。
灵活性 非常高,每一行的长度都可以不同。 较低,所有行的长度必须相同(在声明时确定)。
内存 每个内部 ArrayList 都有自己的对象头,可能占用更多内存。 内存是连续的,结构紧凑。
  • 何时使用二维 ArrayList

    • 当你需要一个灵活的、可变大小的二维结构时。
    • 当每一行的长度可能不同时。
    • 当你主要进行增删操作,而对性能要求不是极端苛刻时。
  • 何时使用二维数组 (int[][])?

    • 当你知道数据的大小固定不变时。
    • 当你需要最高性能的随机访问时(在游戏开发、科学计算中)。
    • 当你处理的是基本数据类型(如 int, double)时,可以避免自动装箱的开销。
分享:
扫描分享到社交APP
上一篇
下一篇