2차원 비정방 행렬은 각 행마다 열의 길이가 다른 2차원 배열을 의미한다. 배열의 구조를 보면 각 행별로 들쑥날쑥한 것을 알 수 있다. 하지만 기본적인 개념은 2차원 정방 행렬과 완벽하게 동일하다. 즉, 1차원 배열을 원소로 포함하고 있는 1차원 배열인 셈이다. 원소인 1차원 배열들의 길이가 다양하다는 것에만 차이가 있다.
2차원 비정방 행렬 배열의 객체를 생성하는 방법은 3가지다. int[][] a = new int[2][3]과 같은 정장 행렬 객체 생성의 첫 번째 방법은 항상 정방 행렬만 생성하므로 비정방 행렬 생성 방법으로는 사용할 수 없다. 그러면 다음 2차원 비정방 행렬에 관한 배열의 객체를 생성하고, 원소 값을 대입하는 3가지 방법을 살펴보자.
방법 ① 배열 객체의 행 성분부터 생성하고 열 성분 생성하기
비정방 행렬 배열을 만드는 첫 번째 방법은 행의 성분만 먼저 생성하고 각각의 행에 열의 성분을 추가하는 방법이다. 각 행마다 길이가 다른 배열을 생성해야 하므로 이렇게 할 수밖에 없다.
🐤배열 객체의 행 성분부터 생성하고 열 성분 생성하기
자료형[][] 참조 변수명 = new 자료형[행의 길이][]; // 열의 길이는 표시하지 않음.
참조 변수명[0] = 1차원 배열의 생성;
참조 변수명[1] = 1차원 배열의 생성;
...
참조 변수명 [행의 길이-1][ = 1차원 배열의 생성;
예
// 1
int[][] a = new int[2][];
a[0] = new int[2]; // 첫 번째 행의 열의 개수
a[0][0] = 1; a[0][1] = 2;
a[1] = new int[3]; // 두 번째 행의 열의 개수
a[1][0] = 3; a[1][1] = 4; a[1][2] = 5;
// 2
int[][] a = new int[2][];
a[0] = new int[]{1, 2};
a[1] = new int[]{3, 4, 5};
예제를 살펴보면 각 행마다 크기가 다른 1차원 배열이 할당된다는 점을 제외하고는 정방 행렬과 동일하다. 따라서 처음 객체를 생성하면 행 성분의 1차원 배열만 생성되며 이후 각 행 성분에 1차원 배열을 할당함으로써 최종적인 2차원 배열 객체가 생성된다. 이상의 과정을 메모리로 표시하면 다음과 같다.
비정방 행렬은 배열의 길이에 주의를 기울여야 한다. 각 행마다 배열의 길이가 다르기 때문이다.
🐤2차원 비정방 배열에서의 배열의 길이 가져오기
System.out.println(a.length); // 2
System.out.println(a[0].length); // 2
System.out.println(a[1].length); // 3
방법 ② 자료형과 대입할 값만 입력하기
방법 ②는 자료형과 함께 이중 중괄호를 사용해 생성할 때 초깃값을 넘겨주는 것이다. 대괄호 안에 행렬의 크기를 넣지 않으며 초깃값에 따라 각 행마다 들어갈 배열의 길이가 결정된다.
🐤자료형과 대입할 값만 입력하기
자료형[][] 참조 변수명 = new 자료형[][] {값, 값, ..., 값}, ..., {값, 값, ..., 값} ;
배열의 길이는 쓰지 않음 0번째 행 데이터 마지막 행 데이터
예
int [][] a = new int[][] {{1, 2}, {3, 4, 5}};
최종적으로 메모리에 저장되는 결과는 앞의 방법과 동일하며, 방법 ②는 다음과 같이 객체의 대입을 분리해 표현할 수 있다.
🐤배열의 선언과 객체의 대입을 분리해 표현 가능
int [][] a = new int[][] {{1, 2} , {3, 4, 5}}; // 0
int[][] b;
b = new int [][]{{1, 2}, {3, 4, 5}}; // 0
방법 ③ 대입할 값만 입력하기
2차원 비정방 행렬 배열의 객체를 생성하는 마지막 방법은 초깃값만 이중 중괄호에 넣어 대입하는 것이다.
🐤대입할 값만 입력하기
자료형[][] 참조 변수명 = {값, 값, ..., 값}, ..., {값, 값, ..., 값} ;
0번째 행 데이터 마지막 행 데이터
예
int[][] a = {{1, 2}, {3, 4, 5}};
2차원 정방 행렬 때와 마찬가지로 방법 ③은 배열의 선언과 객체 대입을 분리할 수 없다는 제한이 있다.
🐤배열의 선언과 객체의 대입을 분리해 표현 불가능
int[][] a = {{1, 2} , {3, 4, 5}}; // 0
int[][] b;
b = {{1, 2}, {3, 4, 5}}; // X
public static void main(String[] args) {
// 비정방 행렬의 선언 및 값 대입 방법 1
int[][] array1 = new int[2][];
array1[0] = new int[2];
array1[0][0] = 1;
array1[0][1] = 2;
array1[1] = new int[3];
array1[1][0] = 3;
array1[1][1] = 4;
array1[1][2] = 5;
System.out.println(array1[0][0] + " " + array1[0][1]);
System.out.println(array1[1][0] + " " + array1[1][1] + " " + array1[1][2]);
System.out.println();
int[][] array2 = new int[2][];
array2[0] = new int[]{1, 2};
array2[1] = new int[]{3, 4, 5};
System.out.println(array2[0][0] + " " + array2[0][1]);
System.out.println(array2[1][0] + " " + array2[1][1] + " " + array2[1][2]);
System.out.println();
// 비정방 행렬의 선언 및 값 대입 방법 2
int [][] array3 = new int[][]{{1, 2},{3, 4, 5}};
System.out.println(array3[0][0] + " " + array3[0][1]);
System.out.println(array3[1][0] + " " + array3[1][1] + " " + array3[1][2]);
System.out.println();
int [][] array4;
array4 = new int[][]{{1, 2},{3, 4, 5}}; // 배열과 객체 대입 분리 가능
System.out.println(array4[0][0] + " " + array4[0][1]);
System.out.println(array3[1][0] + " " + array3[1][1] + " " + array3[1][2]);
System.out.println();
// 비정방 행렬의 선언 및 값 대입 방법 3
int[][] array5 = {{1, 2}, {3, 4, 5}};
System.out.println(array5[0][0] + " " + array5[0][1]);
System.out.println(array5[1][0] + " " + array5[1][1] + " " + array5[1][2]);
System.out.println();
//int[][] array6;
//array6 = {{1, 2}, {3, 4, 5}}; // 배열과 객체 대입 불가능
결과