본문 바로가기
자바의정석

자바의 정석 - 배열(Array)

by 승승구리 2021. 12. 14.

배열(Array)

배열이란?

- 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것

배열을 왜 사용할까?

- 만약 1만개의 숫자를 저장하기 위해서 1만개의 int형 배열을 선언한다고 생각하면 머리가 아플것이다. 이런 경우에 배열을 사용하면 많은 양의 데이터를 손쉽게 다룰 수 있다.

더보기

Q: 배열은 같은 타입의 데이터만 묶을 수 있다, 그렇다면 다른 타입의 변수들을 묶으려면 어떻게 해야할까?

-> 클래스를 사용한다.

배열 예제

한 한급의 시험점수를 저장하려고 한다. 학생 5명의 점수를 저장하기 위해서는 아래와 같이 5개의 변수를 선언해야 한다.

int score1, score2, score3, score4, score5;

변수 5번 선언하는 대신 배열을 이용하면 다음과 같이 간단히 처리할 수 있다. 변수의 선언과 달리 다뤄야할 데이터의 수가 아무리 많아도 단지 배열의 길이만 바꾸면 된다.

int[] score = new int[5]; // 5개의 int 값을 저장할 수 있는 배열을 생성한다.

값을 저장할 수 있는 공간은 score[0] 부터 score[4]까지 모두 5개이며, 변수 score는 배열을 다루는데 필요한 참조변수일 뿐 값을 저장하기 위한 공간은 아니다.

변수와 달리 배열은 각 저장공간이 연속적으로 배치되어 있다는 특징이 있다.

 

배열의 선언과 생성

선언방법 선언 예
타입[] 변수이름; int score;
String[] name;
타입 변수이름[]; int score[];
String name[];

배열의 생성

배열을 선언한 다음에는 배열을 생성해야한다. 배열을 선언하는 것은 단지 참조변수를 위한 공간이 만들어질 뿐이고(Stack),

배열을 생성해야만 비로소 값을 저장할 수 있는 공간(Heap)이 만들어진다.

배열을 생성하기 위해서는 연산자 'new'와 함께 배열의 타입과 길이를 지정해 주어야 한다.
int[] score; // int타입의 배열을 다루기 위한 참조변수 score선언
score = new int[5]; // int타입의 값 5개를 저장할 수 있는 배열

// 배열의 선언과 생성을 동시에 가능하다.
타입[] 변수이름 = new 타입[길이];
int[] score = new int[5];

배열의 생성과정

int[] score;

int형 배열 참조변수 score를 선언한다. 데이터를 저장할 수 있는 공간은 아직 마련되지 않았다.

score = new int[5];

연산자 'new'에 의해서 메모리의 빈 공간에 5개의 int형 데이터를 저장할 수 있는 공간이 마련된다.

그리고 각 배열요소는 자동적으로 int의 기본값(default)인 0으로 초기화 된다.

마지막으로 대입 연산자'='에 의해 배열의 주소가 int형 배열 참조변수 score에 저장된다.

 

배열의 길이와 인덱스

배열의 요소(=element) : 생성된 배열의 각 저장공간

배열이름[인덱스]의 형식으로 배열의 요소 접근.

인덱스(index)는 배열의 요소마다 붙여진 일련번호로 각 요소를 구별하는데 사용된다.

인덱스는 0부터 시작한다.

인덱스(index)의 범위는 0부터 '배열길이-1'까지

예를 들어 길이가5인 배열은 모두 5개의 요소(저장공간)을 가지며 인덱스의 범위는 0-4까지 이다.

score[3] = 100; // 배열 score의 4번째 요소에 100을 저장한다.
int value = score[3]; // 배열 score의 4번째 요소에 저장된 값을 읽어서 value에 저장

 

배열의 또 다른 장점은 index로 상수 대신 변수나 수식도 사용할 수 있다는 것이다.

score[0] = 0;             
score[1] = 10;                            for (int i=0; i < 5; i++){
score[2] = 20;            ------->              score[i] = i * 10;
score[3] = 30;                            }
score[4] = 40;

for문의 제어변수 i는 배열의 index로 사용하기에 딱 알맞아서, 배열을 다룰 때 for문은 거의 필수적이다.

만일 아래와 같이 괄호[]안에 수식이 포함된 경우, 이 수식이 먼저 계산된다. 그래야만 배열의 몇 번째 요소인지 알 수 있기 때문이다.

int tmp = score[i+1];

배열사용 주의점

index의 범위를 벗어난 값을 index로 사용하지 않아야 한다는 것이다.

컴파일러는 이러한 실수를 걸러주지 못한다. 그래서 유효한 범위의 값을 index로 사용하는 것은 전적으로 개발자의 책임이다. 유효하지 않은 값을 index로 사용하면, 무사히 컴파일을 마쳤더라도 실행 시에 에러(ArrayIndexOutOfBoundsException)가 발생한다.

 

class ArrayEx1 {
	public static void main(String[] args) {
    	int[] score = new int[5];
        in k = 1;
        
        score[0] = 50;
        score[1] = 60;
        score[k+1] = 70; // score[2] = 70
        score[3] = 80;
        score[4] = 90;
        
        int tmp = score[k+2] + score[4]; // int tmp = score[3] + score[4]
        
        // for문으로 배열의 모든 요소를 출력한다.
        for (int i = 0; i < 5; i++) {
        	System.out.printf("score[%d]:%d%n", i, socre[i]);
        }
        
        System.out.printf("tmp:%d%n", tmp);
        System.out.printf("score[%d]:%d%n", 7, score[7]); // index의 범위를 벗어난 값
    }
}

실행시 에러 발생 (ArrayIndexOutOfBoundsException) : 배열의 인덱스가 유요한 범위를 넘었다는 뜻

 

배열의 길이

앞서 배운것과 같이 배열을 생성할 때 괄호[]안에 배열의 길이를 적어줘야 한다.

배열의 길이는 배열의 요소의 개수, 값을 저장할 수 있는 공간의 개수다.

배열의 길이의 최대값은 int타입의 최대값 (약 20억)

타입[] 배열이름 = new 타입[길이];
int[] arr = new int[5]; // 길이가 5인 int형 배열

자바에서 '배열의 길이가 0일 수도 있다.'

배열이름.length

자바에서는 JVM이 모든 배열의 길이를 별도로 관리하며, '배열이름.length'를 통해서 배열의 길이에 대한 정보를 얻을 수 있다.

아래의 코드에서 배열 arr의 길이가 5이므로 arr.length의 값 역시 5가 된다.

int[] arr = new int[5]; // 길이가 5인 int배열
int tmp = arr.length; // arr.length의 값은 5이고 tmp에 5가 저장된다.

배열은 한번 생성하면 길이를 변경할 수 없다. 따라서 배열이름.length는 상수이므로, 값을 읽기(read)만 가능하고 변경(write)는 할 수 없다.

int[] arr = new int[5];
arr.length = 10; // 에러, 배열의 길이는 변경할 수 없음.

배열의 길이를 배열이름.length를 사용하는 것이 코드의 관리가 쉽고 에러가 발생할 확률이 적어진다.

 

배열의 길이 변경하기

배열의 길이는 변경할 수 없는데, 만약 배열의 길이를 늘려야 하는 경우에는 어떻게 해야할까?

배열의 길이를 변경하는 방법
    1. 더 큰 배열을 새로 생성한다.
    2. 기존 배열의 내용을 새로운 배열에 복사

이러한 작업들은 꽤나 비용이 많이 들기 때문에, 처음부터 배열의 길이를 넉넉하게 잡아줘서 새로 배열을 생성해야하는 상황이 가능한 적게 발생하도록 해야 한다. 그렇다고 해서 배열의 길이를 너무 크게 잡으면 메모리를 낭비하게 되므로, 기존의 2배정도의 길이로 생성하는 것이 좋다.

 

배열의 초기화

배열의 길이가 큰 경우에는 for문을 이용하는 것이 좋다.

int[] score = new int[5];

for (int i = 0; i < score.length; i++) {
	score[i] = i * 10 + 50;
}

그러나 for문으로 배열을 초기화하려면, 저장하려는 값에 일정한 규칙이 있어야만 가능하기 때문에 자바에서는 다음과 같이 배열을 간단히 초기화 할 수 있는 방법을 제공한다.

int[] score = new int[] { 50, 60, 70, 80, 90 }; // 배열의 생성과 초기화를 동시에

괄호{}안에 저장할 값들을 쉼표로 구분해서 나열하면 되며, 괄호[] 안에 배열의 길이는 적지 않는다. 괄호{}안에 적힌 값의 개수에 의해 배열의 길이가 자동적으로 결정되기 때문이다.

int[] score = new int[]{ 50, 60, 70, 80, 90 };
int[] score = { 50, 60, 70, 80, 90 }; // new int[]를 생략할 수 있음

위와 같이 'new 타입[]'을 생략하여 코드를 더 간단히 할 수도 있다.

다만 다음과 같이 배열의 선언과 생성을 따로 하는 경우에는 생략할 수 없다.

int[] score;
score = new int[]{ 50, 60, 70, 80, 80 }; // OK
score = { 50, 60, 70, 80, 90 }; // 에러. new int[]를 생략할 수 없음.

그리고 괄호{}안에 아무 것도 넣지 않으면, 길이가 0인 배열이 생서오딘다. 참조변수의 기본 값은 null이지만, 배열을 가리키는 참조변수는 null대신 길이가 0인 배열로 초기화하기도 한다. 아래의 세 문장은 모두 길이가 0인 배열을 생성한다.

int[] score = new int[0]; // 길이가 0인 배열
int[] score = new int[]{}; // 길이가 0인 배열
int[] score = {}; // 길이가 0인 배열, new int[]가 생략됨.

배열의 출력

배열에 저장된 값을 확인할 때도 for문을 사용하면 된다.

int[] iArr = { 100, 95, 80, 70, 60 };

// 배열의 요소를 순서대로 하나씩 출력
for (int i = 0; i < iArr.length; i++) {
	System.out.println(iArr[i]);
}

더 간단한 방법은 'Arrays.toString(배열이름)'메서드를 사용하는 것이다.

이 메서드는 배열의 모든 요소를 '[첫번째 요소, 두번째 요소, ...]'와 같은 형식의 문자열로 만들어서 반환한다 .

Arrays.toString() 메서드를 사용하려면 import java.util.*; 를 추가해야 한다.

int[] iArr = { 100, 95, 80, 70, 60 };
// 배열 iArr의 모든 요소를 출력한다. [100, 95, 80, 70, 60]이 출력된다.
System.out.println(Arrays.toString(iArr));

만일 iArr의 값을 바로 출력하면 어떻게 될까?

'타입@주소'의 형식으로 출력된다. [I@14318bb] [I는 1차원 int배열이라는 의미 '@' 뒤에 나오는 16진수는 배열의 주소인데 리제 주소가 아닌 내부 주소이다.

// 배열을 가리키는 참조변수 iArr의 값을 출력한다.
System.out.println(iArr); // [I@14318bb와 같은 형식의 문자열이 출력된다. [타입@주소

예외적으로 char배열은 println메서드로 출력하면 각 요소가 구분자없이 그대로 출력되는데, 이것은 println메서드가 char배열일 때만 이렇게 동작하도록 작성되었기 때문이다.

char[] chArr = { 'a', 'b', 'c', 'd' };
System.out.println(chArr); // abcd가 출력된다.

배열의 복사

배열을 복사하는 방법은 두 가지가 있다. 1. for문을 이용해서 배열을 복사하는 방법

int[] arr = new int[5];
int[] tmp = new int[arr.length*2]; // 기존 배열보다 길이가 2배인 배열 생성

for (int i = 0; i < arr.length; i++)
	tmp[i] = arr[i]; // arr[i]의 값을 tmp[i]에 저장

arr = tmp; // 참조변수 arr이 새로운 배열을 가리키게 한다.

1. 배열 arr의 길이인 arr.length의 값이 5이므로 길이가 10인 int배열 tmp가 생성되고, 배열 tmp의 각 요소는 int의 기본값인 0으로 초기화된다.

----- int[] tmp = new int[arr.length*2];
----> int[] tmp = new int[5*2];
----> int[] tmp = new int[10];

2. for문을 이용해서 배열 arr의 모든 요소에 저장된 값을 하나씩 배열 tmp에 복사한다.

for (int i = 0; i < arr.length; i++) {
	tmp[i] = arr[i];
}

3. 참조변수 arr에 참조변수 tmp의 값을 저장한다. arr의 값은 0x100에서 0x200으로 바뀌고, arr은 배열 tmp를 가리키게 된다.

arr = tmp; // 변수 tmp에 저장된 값을 변수 arr에 저장한다.

결국 참조변수 arr과 tmp는 같은 배열을 가리키게 된다. 즉, 배열 arr과 배열 tmp는 이름만 다를 뿐 동일한 배열이다. 그리고 전에 arr이 가리키던 배열은 더 이상 사용할 수 없게 된다.

* 배열은 참조변수를 통해서만 접근할 수 있기 때문에, 자신을 가리키는 참조변수가 없는 배열은 사용할 수 없다.

이렇게 쓸모없게 된 배열은 JVM의 가비지 컬렉터(GC)에 의해 자동적으로 메모리에서 제거된다.

2. Sysyem.arraycopy()를 이용한 배열의 복사

for문 대신 System클래스의 arraycopy()를 사용하면 보다 간단하고 빠르게 배열을 복사할 수 있다.

for문은 배열의 요소 하나하나에 접근해서 복사하지만, arraycopy()는 지정된 범위의 값들을 한 번에 통째로 복사한다. 각 요소들이 연속적으로 저장되어 있다는 배열의 특성때문에 이렇게 처리하는 것이 가능한 것이다.

배열의 복사는 for문보다 System.arraycopy()를 사용하는 것이 효율적이다.

arraycopy()를 호출할 때는 어느 배열의 몇 번째 요소에서 어느 배열로 몇 번째 요소로 몇 개의 값을 복사할 것인지 지정해줘야 하는데, 다음과 같이 생각하면 이해하기 쉽다.

System.arraycopy(num, 0, newNum, 0, num.length);
// num[0] 에서 newNum[0]으로 num.length개의 데이터를 복사

이때 복사하려는 배열의 위치가 적절하지 못하여 복사하려는 내용보다 여유 공간이 적으면 에러(ArrayIndexOutOfBoundsException)가 발생한다.

 

배열의 활용

총합과 평균 : 배열의 모든 요소를 더해서 총합과 평균을 구한다.

class ArrayEx5 {
	public static void main(String[] args) {
    	int sum = 0;
        float vaerage = 0f;
        
        int[] score = { 100, 88, 100, 100, 90 };
        
        for (int i = 0; i < score.length; i++) {
        	sum += score[i];
        }
        average = sum / (float)score.length; // 계산결과를 float로 얻기 위함.
        
        System.out.println("총점 : " + sum);
        System.out.println("평균 : " + average);
    }
}

최대값과 최소값 : 배열의 요소 중에서 제일 큰 값과 제일 작은 값을 찾는다.

class ArrayEx6 {
	public static void main(String[] args) {
    	int[] score = { 79, 88, 91, 33, 100, 55, 95 };
        
        int max = score[0]; // 배열의 첫 번째 값으로 최대값을 초기화 한다.
        int min = score[0]; // 배열의 첫 번째 값으로 최소값을 초기화 한다.
        
        for (int i = 1; 1 < socre.length; i++) {
        	if (score[i] > max) {
            	max = score[i];
            } else if (score[i] < min) {
            	min = score[i];
            }
        }
        
        System.out.println("최대값 : " + max);
        System.out.println("최소값 : " + min);
    
    }

}

섞기(shuffle) : 배열의 요소의 순서를 반복해서 바꾼다. (카드섞기)

class ArrayEx7 {
	public static void main(String[] args) {
    	int[] numArr = new int[10];
        
        for (int i = 0; i M numArr.length; i++) {
        	numArr[i] = i; // 배열을 0-9까지의 숫자로 초기화
            System.out.print(numArr[i]);
        }
        System.out.println();
        
        for (int i = 0; i < 100; i++) {
        	int n = (int)(Math.random() * 10); // 0-9중의 한개의 값을 랜덤으로 얻는다.
            int tmp = numArr[0];
            numArr[0] = numArr[n];
            numArr[n] = tmp;
        }
        
        for (int i = 0; i < numArr.length; i++) {
        	System.out.println(numArr[i]);
        }
    
    }

}
int tmp = numArr[0];                     int tmp = numArr[0];
numArr[0] = numArr[n];       --------->  numArr[0] = numArr[3];
numArr[n] = tmp;                         numArr[3] = tmp;

섞기(shuffle) : 배열의 요소의 순서를 반복해서 바꾼다. (로또번호생성)

class ArrayEx8 {
	public static void main(String[] args) {
    	// 45개의 정수값을 저장하기 위한 배열 생성
        int[] ball = new int[45];
        
        // 배열의 각 요소에 1~45의 값을 저장한다.
        for (int i = 0; i < ball.length; i++) {
        	ball[i] = i+1; // ball[0]에 1이 저장된다.
        }
        
        int temp = 0; // 두 값을 바꾸는데 사용할 임시변수
        int j = 0; // 임의의 값을 얻어서 저장할 변수
        
        // 배열의 i번째 요소와 임의의 요소에 저장된 값을 서로 바꿔서 값을 섞는다.
        // 0번째 부터 5번째 요소까지 모두 6개만 바꾼다.
        for (int i = 0; i < 6; i++) {
        	j = (int)(Math.random() * 45); // 0-44범위의 임의의 값을 얻는다.
            	temp = ball[i];
            	ball[i] = ball[j];
            	ball[j] = temp;
        }
        
        // 배열 ball의 앞에서부터 6개의 요소를 출력한다.
        for (int i = 0; i < 6; i++)
        	System.out.printf("ball[%d]=%d%n", i, ball[i]);
    
    }

}

임의의 값으로 배열 채우기 : 연속 또는 불연속적인 값들로 배열을 초기화한다.

import java.util.* // Arrays.toString()을 사용하기 위해 추가

class ArrayEx9 {
	public static void main(String[] args) {
    	int[] code = { -4, -1, 3, 6, 11 }; // 불연속적인 값들로 구성된 배열
        int[] arr = new int[10];
        
        for (int i = 0; i < arr.length; i++) {
        	int tmp = (int)(Math.random() * code.length);
           	arr[i] = code[tmp];
        }
        
        System.out.println(Arrays.toString(arr));
    
    }

}

정렬하기 : 오름차순, 내림차순으로 배열을 정렬 

class ArrayEx10 {
	public static void main(String[] args) {
    	int[] numArr = new int[10];
        
        for (int i = 0; i < numArr.length; i++) {
        	System.out.print(numArr[i] = (int)(Math.random() * 10));
        }
        Sysyem.out.println();
        
        for (int i = 0; i < numArr.length-1; i++) {
        	boolean changed = false; // 자리바꿈이 발생했는지를 체크한다.
            
            for (int j = 0; j < numArr.length-1-i; j++) {
            	if (numArr[j] > numArr[j+1]) {
                	int temp = numArr[j];
                    numArr[j] = numArr[j+1];
                    numArr[j+1] = temp;
                    changed = true; // 자리바꿈이 발생했으니 changed를 true로 변경.
                }
            }
            
            if (!changed) break; // 자리바꿈이 없으면 반복문을 벗어난다.
            
            for(int k = 0; k < numArr.length; k++)
            	System.out.print(numArr[k]); // 정렬된 결과를 출력한다.
            System.out.println();
        }
    }

}

빈도수 구하기 : 배열에 어떤 값이 몇개 들어있는지 세어서 보여준다.

class ArrayEx11 {
	public static void main(String[] args) {
    	int[] numArr = new int[10];
        int[] counter = new int[10];
        
        for (int i = 0; i < numArr.length; i++) {
        	numArr[i]  (int)(Math.random() * 10); // 0-9의임의의 수를 배열에 저장
            System.out.prinf(numArr[i]);
        }
        System.out.println();
        
        for (int i = 0; i < numArr.length; i++) {
        	counter[numArr[i]]++;
        }
        
        for (int i = 0; i < numArr.length; i++) {
        	System.out.println(i + "의 개수 : " + counter[i]);
        }
    
    }

}

 

String배열

1. String 배열의 선언과 생성

String[] name = new Stringp[3]; // 3개의 문자열을 담을 수 있는 배열을 생성한다.

3개의 String 타입의 참조변수를 저장하기 위한 공간이 마련되고, 참조형 변수의 기본값은 null이므로 각 요소의 값은 null로 초기화 된다.

2. String배열의 초기화

String[] name = new String[3]; // 길이가 3인 String 배열을 생성
name[0] = "Kim";
name[1] = "Park";
name[2] = "Yi";

String[] name = new Stirng[]{"Kim", "Park", "Yi"};
String[] name = { "Kim", "Park", "Yi" }; // new String[]을 생략할 수 있음

public class Q07 {
    public static void main(String[] args) {
        char[] hex = { 'C', 'A', 'F', 'E' };

        String[] binary = { "0000", "0001", "0010", "0011"
                            , "0100", "0101", "0110", "0111"
                            , "1000", "1001", "1010", "1011"
                            , "1100", "1101", "1110", "1111" };
        String result = "";

        for (int i = 0; i < hex.length; i++) {
            if (hex[i] >= '0' && hex[i] <= '9') {
                result += binary[hex[i] - '0']; // '8' - '0'의 결과는 8이다.
            } else {
                result += binary[hex[i] - 'A' + 10]; // 'C' - 'A'의 결과는 2
            }
        }

        System.out.println("hex:" + new String(hex));
        System.out.println("binary:" + result);
    }
}

2.3 char배열과 String 클래스

String클래스는 char배열에 기능을 추가한 것이다.

char배열과 String클래스의 한 가지 중요한 차이

- String객체(문자열)는 읽을수만 있을 뿐 내용을 변경할 수 없다는 것이다.

String str = "Java";
str = str + "8"; // "Java8"이라는 새로운 문자열이 str에 저장된다.
System.out.println(str); // "Java8"

위의 문장에서 문자열 str의 내용이 변경되는 것 같지만, 문자열은 변경할 수 없으므로 새로운 내용의 문자열이 생성된다. ( * String에 대해서 더 깊이 학습 필요 )

* 변경 가능한 문자열을 다루려면, StringBuffer클래스를 사용하면 된다.

 

String클래스의 주요 메서드

메서드 설명
char charAt(int index) 문자열에서 해당 위치(index)에 있는 문자를 반환한다.
int length() 문자열의 길이를 반환한다.
String substring(int from, int to) 문자열에서 해당 범위(from~to)에 있는 문자열을 반환한다.(to는 범위에 포함되지 않음)
boolean equals(String str) 문자열의 내용이 같은지 확인한다. 같으면 결과는 true, 다르면 false
char[] toCharArray() 문자열을 문자배열(char[])로 변환해서 반환한다.

equals() 메서드

- 문자열의 내용이 같은지 다른지 확인하는데 사용한다.

- 기본형 변수의 값을 비교하는 경우 '=='연산자를 사용하지만, 문자열의 내용을 비교할 때는 equals()를 사용해야 한다.

 

equasl() 메서드 주의점!

equals() 메서드는 대소문자를 구분한다는 점에 주의해야 한다.

대소문자를 구분하지 않고 비교하려면 equals()대신 equalsIgnoreCase()를 사용해야한다.

 

char배열과 String클래스의 변환가끔 char배열을 String클래스로 변환하거나, 또는 그 반대로 변환해야하는 경우가 있다.

char[] chArr = { 'A', 'B', 'C' };
String str = new Stirng(chArr); // char배열 -> String
char[] tmp = str.toCharArray(); // String -> char배열

3. 다차원 배열

3.1 2차원 배열의 선언과 인덱스

선언 방법 선언 예
타입[][] 변수이름; int[][] score;
타입 변수이름[][]; int score[][];
타입[] 변수이름[]; int[] score[];
int[][] score = new int[4][3]; // 4행 3열의 2차원 배열을 생성한다.

2차원 배열의 index

2차원 배열은 행(row)와 열(column)로 구성되어 있기 때문에 index도 행과 열에 각각 하나씩 존재한다. '행index'의 범위는 '0~행의 길이-1'이고 '열index'의 범위는 '0~열의 길이-1'이다. 그리고 2차원 배열의 각 요소에 접근하는 방법은 '배열이름[행index][열index]'이다.

int[][] score = new int[4][3]; // 4행 3열의 2차원 배열 score를 생성

score[0][0] = 100; // 배열 score의 1행 1열에 100을 저장
System.out.println(socre[0][0]); // 배열 score의 1행 1열의 값을 출력

3.2 2차원 배열의 초기화

int[][] arr = new int[][] { {1, 2, 3}, {4, 5, 6} };
int[][] arr = { {1, 2, 3}, {4, 5, 6} }; // new int[][]가 생략됨
int[][] arr = {
		{1, 2, 3},
                {4, 5, 6}
	};
int[][] score = {
		{100, 100, 100},
                {20, 20, 20},
                {30, 30, 30},
                {40, 40, 40},
                {50, 50, 50}
};

for문을 이용해서 2차원 배열을 초기화한다면 다음과 같을 것이다.

for (int i = 0; i < score.length; i++) {
	for (int j = 0; j < score[i].length; j++) {
    	score[i][j] = 10;
    }
}
public class Q08 {
    public static void main(String[] args) {
        int[][] score = {
                { 100, 100, 100 },
                { 20, 20, 20 },
                { 30, 30, 30 },
                { 40, 40, 40 }
        };

        int sum = 0;

        for (int i = 0; i < score.length; i++) {
            for (int j = 0; j < score[i].length; j++) {
                System.out.printf("score[%d][%d] = %d%n", i, j, score[i][j]);
            }
        }

        for (int[] tmp : score) {
            for (int i : tmp) {
                sum += i;
            }
        }

        System.out.println("sum=" + sum);
    }
}
public class Q08 {
    public static void main(String[] args) {
        int[][] score = {
                { 100, 100, 100 },
                { 20, 20, 20 },
                { 30, 30, 30 },
                { 40, 40, 40 },
                { 50, 50, 50 }
            };

        // 과목별 총점
        int korTotal = 0;
        int engTotal = 0;
        int mathTotal = 0;

        System.out.println("번호 국어 영어 수학 총점 평균");
        System.out.println("===========================");

        for (int i = 0; i < score.length; i++) {
            int sum = 0; // 개인별 총점
            float avg = 0.0f; // 개인별 평균

            korTotal += score[i][0];
            engTotal += score[i][1];
            mathTotal += score[i][2];
            System.out.printf("%3d", i+1);

            for (int j = 0; j < score[i].length; j++) {
                sum += score[i][j];
                System.out.printf("%5d", score[i][j]);
            }

            avg = sum/score[i].length; // 평균계산
            System.out.printf("%5d %5.1f%n", sum, avg);
        }

        System.out.println("==================================");
        System.out.printf("총정: %3d %4d %4d%n", korTotal, engTotal, mathTotal);
    }
}

3.3 가변 배열

int[][] score = new int[5][3]; // 5행 3열의 2차원 배열 생성
int[][] score = new int[5][]; // 두 번째 차원의 길이는 지정하지 않는다.
score[0] = new int[3];
score[1] = new int[3];
score[2] = new int[3];
score[3] = new int[3];
score[4] = new int[3];

2차원 배열을 생성하면 직사각형 테이블 형태의 고정적인 배열만 생성할 수 있지만, 각 행마다 다른 길이의 배열으 생성하는 것이 가능하다.

 

3.4 다차원 배열의 활용

import java.util.Scanner;

public class Q09 {
    // 좌표에 X표하기
    public static void main(String[] args) {
        final int SIZE = 10;
        int x = 0, y = 0;

        char[][] board = new char[SIZE][SIZE];
        byte[][]  shipBoard = {
                { 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1
                { 1, 1, 1, 1, 0, 0, 1, 0, 0 }, // 2
                { 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 3
                { 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 4
                { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 5
                { 1, 1, 0, 1, 0, 0, 1, 0, 0 }, // 6
                { 0, 0, 0, 1, 0, 0, 1, 0, 0 }, // 7
                { 0, 0, 0, 1, 0, 0, 1, 0, 0 }, // 8
                { 0, 0, 0, 0, 0, 1, 1, 1, 0 }, // 9
            };

        // 1행에 행번호를, 1열에 열번호를 저장한다.
        for (int i = 1; i < SIZE; i++)
            board[0][i] = board[i][0] = (char) (i+'0');

        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("좌표를 입력하세요. (종료는 00)>");
            String input = scanner.nextLine(); // 화면입력받은 내용을 input에 저장

            if (input.length() == 2) {
                x = input.charAt(0) - '0'; // 문자를 숫자로 변환
                y = input.charAt(1) - '0'; // 문자를 숫자로 변환

                if (x == 0 && y == 0)
                    break;
            }

            if (input.length() != 2 || x <= 0 || x >= SIZE || y <= 0 || y >= SIZE) {
                System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
                continue;
            }

            // shipBoard[x-1][y-1]의 값이 1이면, 'O'을 board[x][y]에 저장한다.
            board[x][y] = shipBoard[x-1][y-1] == 1 ? 'O' : 'X';

            // 배열 board의 내용을 화면에 출력한다.
            for (int i = 0; i < SIZE; i++) {
                System.out.println(board[i]); // board[i]는 1차원 배열
            }
            System.out.println();
        }

    }
}
import java.util.Scanner;

public class Q11 {
    // 단어 맞추기
    public static void main(String[] args) {
        String[][] words = {
                {"chair", "의자"},
                {"computer", "컴퓨터"},
                {"integer", "정수"}
        };

        Scanner scanner = new Scanner(System.in);

        for (int i = 0; i < words.length; i++) {
            System.out.printf("Q%d. %s의 뜻은?", i+1, words[i][0]);

            String tmp = scanner.nextLine();

            if (tmp.equals(words[i][1])) {
                System.out.printf("정답입니다. %n%n");
            } else {
                System.out.printf("틀렸습니다. 정답은 %s입니다. %n%n", words[i][1]);
            }
        }
    }
}