[Java] 배열
배열(array)이란?
같은 타입의 여러 변수를 하나의 묶음으로 다루는 것을 '배열(array)' 이라고 한다.
배열의 선언과 생성
선언 방법 | 선언 예 |
타입[ ] 변수이름; | int[] score; String[] name; |
타입 변수이름[ ]; | int score[]; String name[] ; |
배열의 생성
배열을 선언한 다음에는 배열을 생성해야 한다. 배열을 선언하는 것은 단지 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어질 뿐이고, 배열을 생성해야만 비로서 값을 저장할 수 있는 공간이 만들어지는 것이다.
타입[ ] 변수이름; // 배열을 선언(배열을 다루기 위한 참조변수 선언) 변수이름 = new 타입[길이]; // 배열을 생성(실제 저장공간을 생성) |
int[] score; //int 타입의 배열을 다루기 위한 참조변수 score선언
score = new int[5]; //int 타입의 값 5개를 저장할 수 있는 배열
--------------------------------------------------------------
타입[] 변수이름 = new 타입[길이]; //배열의 선언과 생성을 동시에
int[] score = new int[5];
배열의 길이와 인덱스
생성된 배열의 각 저장공간을 ' 배열의 요소(element)'라고 하며, '배열이름[인덱스]'의 형식으로 배열의 요소에 접근한다.
인덱스는 배열의 요소마다 붙여진 일련번호로 각 요소를 구별하는데 사용된다.
"인덱스(index)의 범위는 0부터 '배열길이 -1'까지." |
int[ ] score = new int[5]; //길이가 5인 int 배열
->길이가 5인 배열은 모두 5개의 요소(저장공간)을 가지며 인덱스의 범위는 1부터 5까지가 아닌 0부터 4까지, 즉
0, 1, 2, 3, 4가 된다.
배열의 값을 저장하고 읽어오는 방법은 변수와 같다. 단지 변수이름 대신 '배열이름[인덱스]'를 사용한다는 점만 다르다.
score[3] = 100; //배열 score의 4번쨰 요소에 100을 저장한다. int value = score[3]; //배열 score의 4번째 요소에 저장된 값을 읽어서 value에 저장. |
배열의 또 다른 장점은 index로 상수 대신 변수나 수식도 사용할 수 있다는 것이다.
score[0] = 0;
score[1] = 10;
score[2] = 20;
score[3] = 30;
score[4] = 40;
for(int i = 0; i < 5; i++){
score[i] = i * 10;
}
for문의 제어변수 i는 배열의 index로 사용하기에 딱 알맞아서, 배열을 다룰 떄 for문은 거의 필수적이다.
class ArrayEX1 {
public static void main(String[] args){
int [] score = new int[5];
int k = 1;
score[0] = 50;
score[1] = 60;
socre[k+1] = 70; //socre[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, score[i]);
}
System.out.printf("tmp:%d%n", tmp);
System.out.printf("score[%d]:%d%n", 7, score[7]); // index 범위를 벗어난 값
score[0] : 50
score[1] : 60
score[2] : 70
score[3] : 80
score[4] : 90
tmp : 170
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Index 7 out of bounds for length 5
at ch05.ArrayEx1.main(ArrayEx1.java:22)
배열의 길이
배열의 길이는 int범위의 양의 정수(0도 포함)이어야 한다. |
배열이름.length
자바에서는 JVM이 모든 배열의 길이를 별도로 관리하며, '배열이름.length'를 통해서 배열의 길이에 대한 정보를 얻을 수 있다.
int[ ] arr = new int[5]; //길이가 5인 int 배열 int tmp = arr.length; //arr.length의 값은 5이고 tmp에 5가 저장된다. |
배열은 한번 생성하면 길이를 변경할 수 없기 때문에, 이미 생성된 배열의 길이는 변하지 않는다. 따라서 '배열이름.length'는 상수다. 즉, 값을 읽을 수만 있을 뿐 변경할 수 없다.
int[] score = new int[5]; //배열의 길이를 6에서 5로 변경
for( int i = 0; i <6; i++){ // 실수로 조건식을 변경하지 않음
System.out.println(score[i]); // 에러발생!!!
}
// 배열의 길이가 변경되었으니 for문에 사용되는 조건의 범위도 변경해주어야 하는데,
// 변경하지 않는 경우 유효범위 에러가 발생한다.
----------------------------------------------------------------------------
// 그래서 for문의 조건식에 배열의 길이를 직접 적어주는 것보다 '배열이름.length'를
// 사용하는 것이 좋다.
int[] score = new int[5]; //배열의 길이를 6에서 5로 변경
for(int i = 0; i<score.length; i++){ // 조건식을 병경하지 않아도 됨.
System.out.println(score[i]);
}
배열의 초기화
배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 배열을 사용하기 전에 따로 초기화를 해주지 않아도 되지만, 원하는 값을 저장하려면 아래와 같이 각 요소마다 값을 지정해 줘야 한다.
int [] score = new int[5]; //길이가 5인 int형 배열을 생성한다.
score[0] = 50; // 각 요소에 직접 값을 저장한다.
score[1] = 60;
score[2] = 70;
score[3] = 80;
score[4] = 90;
//배열의 길이가 큰 경우에는 요소 하나하나 지정하기 보다는 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 = {50,60,70,80,90};//new int[] 생략 가능
배열의 출력
int[] iArr = {100, 95, 80, 70, 60};
// 배열의 요소를 순서대로 하나씩 출력
for(int i=0; i< iArr.length; i++){
System.out.println(iArr[i]);
}
int[] iArr = {100, 95, 80, 70, 60};
System.out.println(Arrays.toString(iArr));
import java.util.*;
public class ArrayEx2 {
public static void main(String[] args) {
int[] iArr1 = new int[10];
int[] iArr2 = new int[10];
// int[] iArr3 = new int[] {100,95,80,70,60};
int[] iArr3 = {100,95,80,70,60};
char[] chArr = {'a','b','c','d'};
for(int i=0; i <iArr1.length; i++) {
iArr1[i] = i+1; // 1~10의 숫자를 순서대로 배열에 넣는다.
}
for(int i=0; i<iArr2.length; i++) {
iArr2[i] = (int)(Math.random()*10) + 1;// 1~10의 값을 배열에 저장
}
//배열의 저장된 값들을 출력한다.
for(int i =0; i <iArr1.length;i++) {
System.out.print(iArr1[i]+",");
}
System.out.println();
System.out.println(Arrays.toString(iArr2));
System.out.println(Arrays.toString(iArr3));
System.out.println(Arrays.toString(chArr));
System.out.println(iArr3);
System.out.println(chArr);
}
}
1,2,3,4,5,6,7,8,9,10,
[5, 4, 1, 2, 5, 9, 6, 5, 8, 5]
[100, 95, 80, 70, 60]
[a, b, c, d]
[I@26f0a63f
abcd
배열의 복사
배열은 한번 생성하면 그 길이를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다며 보다 큰 배열을 새로 만들고
이전 배열로 부터 내용을 복사해야한다.
▣ for문을 이용한 배열의 복사
//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이 새로운 배열을 가르키게 한다.
public class ArrayEx3 {
public static void main(String[] args) {
int[] arr = new int[5];
//배열 arr에 1~5를 저장한다.
for(int i=0; i<arr.length; i++)
arr[i] = i+1;
System.out.println("[변경전]");
System.out.println("arr.length :" +arr.length);
for(int i =0; i < arr.length; i++)
System.out.println("arr["+i+"] :"+arr[i]);
int[] tmp = new int[arr.length*2];
// 배열 arr에 저장된 값들을 배열 tmp에 복사한다.
for(int i =0; i<arr.length; i++)
tmp[i] = arr[i];
arr = tmp; //tmp에 저장된 값을 arr에 저장한다.
System.out.println("[변경후]");
System.out.println("arr.length:" + arr.length);
for(int i =0; i<arr.length; i++)
System.out.println("arr["+i+"]:" +arr[i]);
}
[변경전]
arr.length :5
arr[0] :1
arr[1] :2
arr[2] :3
arr[3] :4
arr[4] :5
[변경후]
arr.length:10
arr[0]:1
arr[1]:2
arr[2]:3
arr[3]:4
arr[4]:5
arr[5]:0
arr[6]:0
arr[7]:0
arr[8]:0
arr[9]:0
▣ System.arraycopy()를 이용한 배열의 복사
for문은 배열의 요소 하나하나에 접근해서 복사하지만, arraycopy()는 지정된 범위의 값들을 한 번에 통떄로 복사한다.
for문 보다 더 효율적인 방법
public class ArrayEx4 {
public static void main(String[] args) {
char[] abc = { 'A', 'B', 'C', 'D'};
char[] num = { '0', '1' ,'2', '3', '4', '5', '6', '7', '8', '9'};
System.out.println(abc);
System.out.println(num);
//배열 abc와 num을 붙여서 하나의 배열(result)로 만든다.
char[] result = new char[abc.length+num.length];
System.arraycopy(abc, 0, result, 0, abc.length);
System.arraycopy(num, 0, result, abc.length, num.length);
System.out.println(result);
// 배열 abc을 배열 num의 첫 번쨰 위치부터 배열 abc 길이만큼 복사
System.arraycopy(abc, 0, num, 0, abc.length);
System.out.println(num);
// number의 인덱스 6위치부터 3개를 복사
System.arraycopy(abc, 0, num, 6, 3);
System.out.println(num);
ABCD
0123456789
ABCD0123456789
ABCD456789
ABCD45ABC9
public class ArrayEx4 {
public static void main(String[] args) {
char[] abc = { 'A', 'B', 'C', 'D'};
char[] num = { '0', '1' ,'2', '3', '4', '5', '6', '7', '8', '9'};
System.out.println(abc);
System.out.println(num);
//배열 abc와 num을 붙여서 하나의 배열(result)로 만든다.
char[] result = new char[abc.length+num.length];
System.arraycopy(abc, 0, result, 0, abc.length);
System.arraycopy(num, 0, result, abc.length, num.length);
System.out.println(result);
// 배열 abc을 배열 num의 첫 번쨰 위치부터 배열 abc 길이만큼 복사
System.arraycopy(abc, 0, num, 0, abc.length);
System.out.println(num);
// number의 인덱스 6위치부터 3개를 복사
System.arraycopy(abc, 0, num, 6, 3);
System.out.println(num);
}
}
ABCD
0123456789
ABCD0123456789
ABCD456789
ABCD45ABC9