[처음부터 다시 하는 JAVA] 2차원 배열
처음부터 다시 하는 자바 공부는 인프런의 김영한 강사님의 강의를 참고해서 공부했다.
2차원 배열 - 시작
지금까지 학습한 배열은 단순히 순서대로 나열되어 있었다. 이것을 1차원 배열이라 한다.
이번에 학습할 2차원 배열은 이름 그대로 하나의 차원이 추가된다. 2차원 배열은 행과 열로 구성된다.
2차원 배열은 int[][] arr = new int[2][3] 와 같이 선언하고 생성한다. 그리고 arr[1][2] 와 같이 사용하는데, 먼저 행 번호를 찾고, 그 다음에 열 번호를 찾으면 된다.
행은 영어로 row(로우), 열은 영어로 column(컬럼)이라 한다. 자주 사용하는 단어이니 알아두자.
2차원 배열의 사용법은 [] 가 하나 추가되는 것을 제외하고는 앞서본 1차원 배열과 같다.
그림의 배열에 들어있는 데이터는 다음과 같다.
arr[행][열] , arr[row][column]
그림의 2차원 배열 데이터
- arr[0][0]: 1
- arr[0][1]: 2
- arr[0][2]: 3
- arr[1][0]: 4
- arr[1][1]: 5
- arr[1][2]: 6
코드를 통해서 2차원 배열의 사용법을 알아보자.
package array;
public class ArrayDi0 {
public static void main(String[] args) {
// 2x3 2차원 배열을 만든다.
int[][] arr = new int[2][3]; //행(row), 열(column)
arr[0][0] = 1; //0행, 0열
arr[0][1] = 2; //0행, 1열
arr[0][2] = 3; //0행, 2열
arr[1][0] = 4; //1행, 0열
arr[1][1] = 5; //1행, 1열
arr[1][2] = 6; //1행, 2열
//0행 출력
System.out.print(arr[0][0] + " "); //0열 출력
System.out.print(arr[0][1] + " "); //1열 출력
System.out.print(arr[0][2] + " "); //2열 출력
System.out.println(); //한 행이 끝나면 라인을 변경한다.
//1행 출력
System.out.print(arr[1][0] + " "); //0열 출력
System.out.print(arr[1][1] + " "); //1열 출력
System.out.print(arr[1][2] + " "); //2열 출력
System.out.println(); //한 행이 끝나면 라인을 변경한다.
}
}
실행 결과
1 2 3 //[0][0], [0][1], [0][2]
4 5 6 //[1][0], [1][1], [1][2]
- 이 코드는 2차원 배열을 만들고, 배열에 값을 1부터 6까지 순서대로 직접 입력한다.
- 다음과 같은 결과를 만들기 위해 0행에 있는 0,1,2열을 출력한다. 그리고 다음으로 1행에 있는 0,1,2열을 출력한다.
2차원 배열 - 리펙토링1
구조 개선 - 행 출력 반복
구조 변경
코드 구조를 보면 비슷한 부분이 반복된다.
//0행 출력
System.out.print(arr[row][0] + " "); //0열 출력
System.out.print(arr[row][1] + " "); //1열 출력
System.out.print(arr[row][2] + " "); //2열 출력
System.out.println(); //한 행이 끝나면 라인을 변경한다.
//1행 출력
System.out.print(arr[1][0] + " "); //0열 출력
System.out.print(arr[1][1] + " "); //1열 출력
System.out.print(arr[1][2] + " "); //2열 출력
System.out.println(); //한 행이 끝나면 라인을 변경한다.
코드를 보면 행을 출력하는 부분이 거의 같다. 차이가 있는 부분은 행에서 arr[0] 으로 시작할지 arr[1] 로 시작할지의 차이다.
다음과 같이 행(row)에 들어가는 숫자만 하나씩 증가하면서 반복하면 될 것 같다.
// row를 0, 1로 변경하면서 다음 코드를 반복
System.out.print(arr[row][0] + " "); //0열 출력
System.out.print(arr[row][1] + " "); //1열 출력
System.out.print(arr[row][2] + " "); //2열 출력
System.out.println(); //한 행이 끝나면 라인을 변경한다.
반복문을 사용하도록 코드를 변경해보자.
package array;
public class ArrayDi1 {
public static void main(String[] args) {
// 2x3 2차원 배열을 만듭니다.
int[][] arr = new int[2][3]; //행(row), 열(column)
arr[0][0] = 1; //0행, 0열
arr[0][1] = 2; //0행, 1열
arr[0][2] = 3; //0행, 2열
arr[1][0] = 4; //1행, 0열
arr[1][1] = 5; //1행, 1열
arr[1][2] = 6; //1행, 2열
for (int row = 0; row < 2; row++) {
System.out.print(arr[row][0] + " "); //0열 출력
System.out.print(arr[row][1] + " "); //1열 출력
System.out.print(arr[row][2] + " "); //2열 출력
System.out.println(); //한 행이 끝나면 라인을 변경한다.
}
}
}
실행 결과
구조 개선 - 열 출력 반복
다음 부분을 보면 같은 코드가 반복된다.
1 2 3
4 5 6
- for문을 통해서 행(row)을 반복해서 접근한다. 각 행 안에서 열(column)이 3개이므로 arr[row][0] , arr[row][1] , arr[row][2] 3번 출력한다. 이렇게하면 for문을 한번 도는 동안 3개의 열을 출력할 수 있다.
- row=0 의 for문이 실행되면 arr[0][0] , arr[0][1] , arr[0][2] 로 1 2 3 이 출력된다.
- row=1 의 for문이 실행되면 arr[1][0] , arr[1][1] , arr[1][2] 로 4 5 6 이 출력된다.
구조 개선 - 열 출력 반복
다음 부분을 보면 같은 코드가 반복된다.
System.out.print(arr[row][0] + " "); //0열 출력
System.out.print(arr[row][1] + " "); //1열 출력
System.out.print(arr[row][2] + " "); //2열 출력
다음과 같이 열(column)에 들어가는 숫자만 하나씩 증가하면서 반복하면 될 것 같다.
//column를 0, 1, 2로 변경하면서 다음 코드를 반복
System.out.print(arr[row][column] + " "); //column열 출력
코드를 수정해보자.
package array;
public class ArrayDi2 {
public static void main(String[] args) {
// 2x3 2차원 배열을 만듭니다.
int[][] arr = new int[2][3]; //행(row), 열(column)
arr[0][0] = 1; //0행, 0열
arr[0][1] = 2; //0행, 1열
arr[0][2] = 3; //0행, 2열
arr[1][0] = 4; //1행, 0열
arr[1][1] = 5; //1행, 1열
arr[1][2] = 6; //1행, 2열
for (int row = 0; row < 2; row++) {
for (int column = 0; column < 3; column++) {
System.out.print(arr[row][column] + " ");
}
}
}
}
- for문을 2번 중첩해서 사용하는데, 첫번째 for문은 행을 탐색하고, 내부에 있는 두번째 for문은 열을 탐색한다.
- 내부에 있는 for문은 앞서 작성한 다음 코드와 같다. for문을 사용해서 열을 효과적으로 출력했다.
System.out.print(arr[row][0] + " "); //0열 출력
System.out.print(arr[row][1] + " "); //1열 출력
System.out.print(arr[row][2] + " "); //2열 출력
2차원 배열 - 리펙토링2
구조 개선 - 초기화, 배열의 길이
이 코드를 보니 2가지 개선할 부분이 있다.
1. 초기화: 기존 배열처럼 2차원 배열도 편리하게 초기화 할 수 있다.
2. for 문에서 배열의 길이 활용: 배열의 길이가 달라지면 for 문에서 row < 2 , column < 3 같은 부분을 같이 변경해야 한다. 이 부분을 배열의 길이를 사용하도록 변경해보자. 배열이 커지거나 줄어들어도 for문의 코드를 변경하지 않고 그대로 유지할 수 있다.
코드를 개선해보자.
package array;
public class ArrayDi3 {
public static void main(String[] args) {
// 2x3 2차원 배열, 초기화
int[][] arr = {
{1, 2, 3},
{4, 5, 6}
};
// 2차원 배열의 길이를 활용
for (int row = 0; row < arr.length; row++) {
for (int column = 0; column < arr[row].length; column++) {
System.out.print(arr[row][column] + " ");
}
System.out.println();
}
}
}
초기화
1차원 배열은 다음과 같이 초기화 한다.
{1,2,3}
2차원 배열은 다음과 같이 초기화 한다. 밖이 행이 되고, 안이 열이 된다. 그런데 이렇게 하면 행열이 잘 안느껴진다.
{{1, 2, 3},{4, 5, 6}}
이렇게 라인을 적절하게 넘겨주면 행과 열이 명확해진다. 따라서 코드를 더 쉽게 이해할 수 있다.
{
{1, 2, 3},
{4, 5, 6}
}
배열의 길이
for 문에서 2차원 배열의 길이를 활용했다.
- arr.length 는 행의 길이를 뜻한다. 여기서는 2가 출력된다.
- {{},{}} 를 생각해보면 arr 배열은 {} , {} 2개의 배열 요소를 가진다.
- arr[row].length 는 열의 길이를 뜻한다. 여기서는 3이 출력된다.
- arr[0] 은{1,2,3} 배열을 뜻한다. 이 배열에는 3개의 요소가 있다.
- arr[1] 은{4,5,6} 배열을 뜻한다. 이 배열에는 3개의 요소가 있다.
잘 동작하는지 확인해보자.
이제 배열의 초기화 부분만 다음과 같이 변경하면 바로 적용된 결과를 확인할 수 있다. 나머지 코드는 변경하지 않아도 된다.
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
구조 개선 - 값 입력
이번에는 배열에 직접 1,2,3 숫자를 적어서 값을 할당하는 것이 아니라, 배열의 크기와 상관없이 배열에 순서대로 1씩 증가하는 값을 입력하도록 변경해보자.
public class ArrayDi4 {
public static void main(String[] args) {
// 2x3 2차원 배열, 초기화
int[][] arr = new int[2][3];
int i = 1;
// 순서대로 1씩 증가하는 값을 입력한다.
for (int row = 0; row < arr.length; row++) {
for (int column = 0; column < arr[row].length; column++) {
arr[row][column] = i++;
}
}
// 2차원 배열의 길이를 활용
for (int row = 0; row < arr.length; row++) {
for (int column = 0; column < arr[row].length; column++) {
System.out.print(arr[row][column] + " ");
}
System.out.println();
}
}
}
- 중첩된 for 문을 사용해서 값을 순서대로 입력한다.
- arr[row][column] = i++ 후의 증감 연산자( ++ )를 사용해서 값을 먼저 대입한 다음에 증가한다.
- 코드에서 int i = 1 으로 i 가 1부터 시작한다.
2차원 배열 선언 부분인 new int[2][3] 을 new int[4][5] 처럼 다른 숫자로 변경해도 잘 동작하는 것을 확인할 수 있다.
new int[4][5]로 변경시 출력
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20