CodeGym /행동 /JAVA 25 SELF /재그드 배열 (Jagged Arrays)

재그드 배열 (Jagged Arrays)

JAVA 25 SELF
레벨 7, 레슨 4
사용 가능

1. 재그드 배열은 2차원 배열과 다릅니다

드디어 많은 사람이 “재그드 배열”이라고 부르는 주제에 도달했습니다 — 영어로는 jagged arrays입니다. 2차원 배열과 달리, 재그드 배열은 길이가 서로 다른 행을 저장할 수 있습니다. 마치 각 건물마다 아파트 수가 다른 건물 단지와 같습니다 — 어떤 건물은 5가구, 다른 건물은 20가구, 또 다른 건물은 단 한 가구만 있는 것처럼요.

재그드 배열은 각 요소가 배열인 배열이며, 내부 배열(‘하위 배열’이라고도 함)의 길이가 서로 다를 수 있습니다.

핵심 차이점:

  • 2차원 배열에서는 각 “행”(그리고 각 “열”)의 요소 개수가 동일합니다. 예: int[][] grid = new int[3][5]; — 항상 3개의 행, 각 행에 5개의 요소가 있습니다.
  • 재그드 배열에서는 각 행의 길이가 제각각일 수 있습니다! 예: int[][] jagged = new int[3][]; — 그런 다음 각 행(하위 배열)을 필요에 맞게 개별적으로 초기화합니다.

시각적으로 보면 다음과 같습니다:

2차원 배열 (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. 재그드 배열 순회와 활용

재그드 배열을 순회하는 것은 2차원 배열과 비슷하지만, 이제 바깥 루프는 행을, 안쪽 루프는 각 행의 요소(길이가 서로 다를 수 있음)를 순회합니다:

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. 재그드 배열의 전형적인 사용 사례

언제 재그드 배열이 2차원 배열보다 유용할까요?

  • 각 사용자마다 서로 다른 개수의 데이터를 저장할 때: 과목별 점수, 구매 이력, 댓글 등.
  • 데이터가 삼각형/계단형 구조일 때(예: 피라미드 출력, 파스칼의 삼각형 등).
  • 메모리를 절약하고 싶을 때: 2차원 배열은 모든 행의 길이가 고정이지만, 재그드 배열은 필요한 만큼만 요소를 둡니다.

실전 예: 학생 성적 매니저

예를 들어 학생이 셋 있고, 수학 과제에 대한 점수가 다음과 같다고 합시다:

학생 점수
0 5, 4
1 3, 4, 4
2 5

이러한 배열을 선언해 봅시다:

int[][] studentMarks = new int[3][];
studentMarks[0] = new int[] { 5, 4 };         // 첫 번째 학생 — 점수 2개
studentMarks[1] = new int[] { 3, 4, 4 };      // 두 번째 학생 — 점수 3개
studentMarks[2] = new int[] { 5 };            // 세 번째 학생 — 점수 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 = {
    { "이반", "표트르" },
    { "마리야", "알렉세이", "세르게이" },
    { "바실리사" }
};

5. 3차원 및 다차원 배열

아마 이미 짐작했겠지만, 배열에 관한 또 하나의 흥미로운 사실이 있습니다. 2차원 배열을 만들 수 있다면 3차원 배열도 만들 수 있을까요?

네, 어떤 차원의 배열이든 만들 수 있습니다. 이런 배열을 다차원 배열이라고 부릅니다.

다차원 배열 선언 방법

대괄호로 필요한 차원의 수를 나열하면 됩니다:

int[][][] cube = new int[2][3][4]; // 2 "층", 3행, 4열
cube[0][1][2] = 99;

여기서는 3차원 배열입니다:

  • 2 — 첫 번째 좌표의 요소 수,
  • 3 — 두 번째 좌표의 요소 수,
  • 4 — 세 번째 좌표의 요소 수.

이런 배열은 연속적으로 저장된 하나의 큰 ‘데이터 큐브’입니다.

3차원 배열 순회

요소에 접근할 때는 모든 인덱스를 함께 지정합니다:

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에서처럼 0부터 시작합니다.
  • 전체 요소 수는 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을 던집니다. 인덱스가 항상 허용 범위, 즉 0부터 length - 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[행][열]. 거꾸로가 아닙니다!

1
과제
JAVA 25 SELF, 레벨 7, 레슨 4
잠금
유연한 플레이어 업적 시스템 🏅
유연한 플레이어 업적 시스템 🏅
1
과제
JAVA 25 SELF, 레벨 7, 레슨 4
잠금
축하 만찬 손님 목록 🥂
축하 만찬 손님 목록 🥂
1
과제
JAVA 25 SELF, 레벨 7, 레슨 4
잠금
미니게임의 총점 🎮
미니게임의 총점 🎮
1
과제
JAVA 25 SELF, 레벨 7, 레슨 4
잠금
센서 판독값으로 본 건물에서 가장 뜨거운 지점 🔥
센서 판독값으로 본 건물에서 가장 뜨거운 지점 🔥
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION