CodeGym /課程 /JAVA 25 SELF /交錯陣列(Jagged Arrays)

交錯陣列(Jagged Arrays)

JAVA 25 SELF
等級 7 , 課堂 4
開放

1. 交錯陣列與二維陣列的不同

我們終於來到許多人稱作「交錯陣列」的主題——英文叫作 jagged arrays。與二維陣列不同,交錯陣列允許每一列擁有不同的長度。這就好比一個住宅群,每棟大樓的戶數各不相同——有的大樓有 5 戶,有的有 20 戶,還有的只有 1 戶。

交錯陣列是一個陣列,其中每個元素本身也是陣列,而且這些內部陣列(也稱為「子陣列」)可以有不同的長度。

關鍵差異:

  • 二維陣列中,每一「列」(以及每一「欄」)都有相同數量的元素。 例:int[][] grid = new int[3][5]; —— 我們永遠有 3 列、每列 5 個元素。
  • 交錯陣列中,每一列都可以有不同的長度! 例:int[][] jagged = new int[3][]; —— 然後再各自初始化每一列(子陣列)。

視覺上可以這樣理解:

二維陣列 (3x3):
┌───┬───┬───┐
│ 1 │ 2 │ 3 │
├───┼───┼───┤
│ 4 │ 5 │ 6 │
├───┼───┼───┤
│ 7 │ 8 │ 9 │
└───┴───┴───┘

交錯陣列(長度不一):
┌───┬───┐
│ 1 │ 2 │
├───┼───┼───┬───┐
│ 3 │ 4 │ 5 │ 6 │
├───┼───┴───┴───┘
│ 7 │
└───┘

2. 宣告與初始化交錯陣列的語法

宣告交錯陣列並不比先前的型別可怕!不用害怕兩組中括號:


int[][] jaggedArray = new int[3][];
交錯陣列的宣告:已指定外層大小,內部陣列尚未建立

這表示我們有一個含 3 個元素的陣列,而且每個元素本身也是 int 陣列。不過內部陣列尚未建立!為了更好理解,我們拆解說明。

逐步初始化交錯陣列

步驟 1 —— 建立主(外層)陣列:

int[][] jaggedArray = new int[3][];

現在我們有 3 個「列」,但此時它們都為 null

步驟 2 —— 建立並配置內部陣列(子陣列):
例如,第一列長度為 2、第二列為 4、第三列為 3

jaggedArray[0] = new int[2]; // 第一列有 2 個元素
jaggedArray[1] = new int[4]; // 第二列有 4 個元素
jaggedArray[2] = new int[3]; // 第三列有 3 個元素

步驟 3 —— 填入數值:
內部陣列就是一般的陣列!例如:

jaggedArray[0][0] = 1;
jaggedArray[0][1] = 2;

jaggedArray[1][0] = 3;
jaggedArray[1][1] = 4;
jaggedArray[1][2] = 5;
jaggedArray[1][3] = 6;

jaggedArray[2][0] = 7;
jaggedArray[2][1] = 8;
jaggedArray[2][2] = 9;

交錯陣列的精簡初始化

如果事先知道資料,也可以一次建立並填好交錯陣列:

int[][] jaggedArray = new int[][]
{
    new int[] { 1, 2 },
    new int[] { 3, 4, 5, 6 },
    new int[] { 7, 8, 9 }
};

或者更精簡些,省略內部陣列的型別:

int[][] jaggedArray = 
{
    { 1, 2 },
    { 3, 4, 5, 6 },
    { 7, 8, 9 }
};

3. 走訪並操作交錯陣列

走訪交錯陣列並不比二維陣列困難;外層迴圈跑各列,內層迴圈跑該列的元素(每列長度可能不同):

for (int i = 0; i < jaggedArray.length; i++) 
{
    System.out.println("列 " + i + ":");
    for (int j = 0; j < jaggedArray[i].length; j++) 
    {
        System.out.print(jaggedArray[i][j] + " ");
    }
    System.out.println();
}

輸出結果:

列 0:
1 2 
列 1:
3 4 5 6 
列 2:
7 8 9 

也可以使用 for-each,就不用自己處理索引:

for (int[] row : jaggedArray) 
{
    for (int value : row) 
    {
        System.out.print(value + " ");
    }
    System.out.println();
}

4. 交錯陣列的典型應用場景

何時交錯陣列比二維陣列更合適?

  • 若每個使用者的資料量不同:各科成績、購買紀錄、留言等。
  • 若資料呈現三角形或階梯狀結構(例如輸出金字塔、帕斯卡三角形等)。
  • 若想節省記憶體:二維陣列的每列都是固定長度,而交錯陣列只會配置所需的元素數。

實例:學生成績管理

假設有三位學生,以下是他們在數學不同作業的分數:

學生 分數
0 5、4
1 3、4、4
2 5

宣告如下陣列:

int[][] studentMarks = new int[3][];
studentMarks[0] = new int[] { 5, 4 };         // 第 1 位學生 — 2 個分數
studentMarks[1] = new int[] { 3, 4, 4 };      // 第 2 位學生 — 3 個分數
studentMarks[2] = new int[] { 5 };            // 第 3 位學生 — 1 個分數

輸出每位學生的分數:

for (int i = 0; i < studentMarks.length; i++) 
{
    System.out.print("學生 " + i + ": ");
    for (int j = 0; j < studentMarks[i].length; j++) 
    {
        System.out.print(studentMarks[i][j] + " ");
    }
    System.out.println();
}

交錯陣列可搭配其他型別

任何型別都能做成交錯陣列:字串、陣列的陣列(更深層!),甚至你自訂的物件.

範例:字串的交錯陣列

String[][] groups = {
    { "Ivan", "Pyotr" },
    { "Mariya", "Aleksey", "Sergey" },
    { "Vasilisa" }
};

5. 三維與多維陣列

再來一個關於陣列的有趣事實,你大概早已猜到。如果可以做二維陣列,那能不能做三維?

可以,陣列可以有任意維度。這類陣列稱為多維

如何宣告多維陣列

只要在中括號中寫上各維度的大小即可:

int[][][] cube = new int[2][3][4]; // 2 「層」、3 列、4 欄
cube[0][1][2] = 99;

這是一個三維陣列:

  • 2 個元素在第一維,
  • 3 —— 在第二維,
  • 4 —— 在第三維。

這樣的陣列就像是一個大的「資料立方體」,依序儲存。

走訪三維陣列

存取元素時需要同時提供所有索引:

for (int i = 0; i < cube.length; i++) 
{
    for (int j = 0; j < cube[i].length; j++) 
    {
        for (int k = 0; k < cube[i][j].length; k++) 
        {
            System.out.print(cube[i][j][k] + " ");
        }
        System.out.println();
    }
    System.out.println("---");
}
  • 索引從零開始,這在 Java 中一向如此。
  • 此陣列共有 2 × 3 × 4 = 24 個元素。

多維陣列的實用範例

  • 2D —— 表格、棋盤、影像。
  • 3D —— 電腦圖學中的「小方塊」、科學計算的資料(例如在不同空間與時間點的溫度)。
  • 4D 以上 —— 較少使用,但可見於高等數學、模擬、機器學習等。

6. 操作多維陣列的常見錯誤

錯誤 №1:陣列越界

最常見的錯誤——嘗試存取不存在的元素,例如:

int[][] arr = new int[2][3];
arr[2][0] = 5; // 錯誤!索引為 2 的列不存在(只有 0 與 1)
arr[0][3] = 7; // 錯誤!索引為 3 的欄不存在(只有 0、1、2)

此類存取會拋出 ArrayIndexOutOfBoundsException。務必確認索引在允許範圍內:從 0length - 1

錯誤 №2:交錯陣列中的列未初始化

如果建立了交錯陣列卻忘了初始化內部陣列,存取時會得到 NullPointerException

int[][] jagged = new int[3][];
jagged[0][0] = 5; // 錯誤!jagged[0] == null

必須先建立內部陣列:jagged[0] = new int[2];

錯誤 №3:錯用陣列長度

matrix.length(列的數量)和 matrix[0].length(欄的數量)搞混。這在複製、走訪、對欄求和時特別常見。

錯誤 №4:假設所有列長度都相同

在交錯陣列中,各列長度可能不同!當你寫 matrix[i][j] 時,請確認 j < matrix[i].length

錯誤 №5:索引順序搞反

有時會搞混:應先是列,再是欄:matrix[row][column]。不要反過來!

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION