배열이란? 같은 타입의 변수를 하나의 묶음으로 다루는 것.
많은 양의 데이터를 저장하기 위해서, 그 데이터의 숫자만큼 변수를 선언해야 한다면 혼란스러울 수 있는데 이때 배열을 이용하면 많은 양의 데이터를 손쉽게 다룰 수 있다. 또한 배열은 연속적인 공간 확보가 필요하기 때문에 인덱스가 길어지면 메모리에서 해당 인덱스의 길이를 선언하여 생성할 수 있을 만큼의 공간을 확보하여 생성한다. 그렇기 때문에 메모리의 낭비가 발생할 수 있다는 단점과 속도가 빠르다는 장점이 있다.
1.1 배열의 선언과 생성
변수타입 [] 변수명 = new 타입[길이];
:: int[] score = new int[5] //→ 배열을 선언(배열을 다루기 위한 참조변수 선언) = new 배열을 생성(실제 저장공간을 생성)
배열을 선언하고 배열을 생성해야 하는데, 여기서 주의할 점은 배열을 선언하는 것은 단지 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어질 뿐이고, 배열을 생성해야만 비로소 값을 저장할 수 있는 공간이 만들어지는 것이다. 배열을 생성하기 위해서는 연산자 'new'와 함게 배열의 '타입'과 '길이'를 지정해줘야 한다.
선언과 생성에 대한 세부설명
1) int[] score = 배열선언
:: int형 배열 score를 선언. 다만 데이터를 저장할 수 있는 공간은 아직 마련되지 않은 상태.
2) new int[5] = 배열생성
:: 연산자 'new'에 의해서 메모리의 빈 공간에 5개의 int형 데이터를 저장할 수 있는 공간이 마련된 상태.
1.2 배열의 길이와 인덱스(저장공간 = 배열의 요소)
배열의 저장공간을 배열의 인덱스(index)라 부르는데 '배열명[인덱스]'의 형식으로 배열의 요소에 접근한다. 인덱스는 배열의 요소마다 붙여진 일련번호로 각 요소를 구별하는데 사용된다. 우리가 변수의 이름을 지을 때 score1, score2 등과 같이 번호를 붙이는 것과 비슷하다고 할 수 있다. 단, 배열의 인덱스는 1이 아닌 0부터 시작한다는 특징이 있다.
배열의 길이와 인덱스에 대한 예제)
int[] score = new int [5]; //정수타입의 배열을 선언한 뒤 인덱스의 길이가 5인 배열을 생성
score[3] = 100; //배열의 4번째 인덱스에 정수 100을 저장
int value = score[3]; //해당 인덱스에 저장된 값을 int타입의 변수 value에 저장
만약 위와 같은 상태로 값을 일일이 전부 넣어준다면 굉장히 귀찮고 힘든 일이 될 수 있기 때문에 앞서 얘기했던 for문을 통해 배열을 선언해 줄 수 있다. 배열과 for문의 관계는 거의 필수적이기 때문에 잘 알아두는 것이 좋다.
배열의 길이를 변경하는 방법
① 더 큰 배열을 새롭게 생성한다.
② 기존 배열의 내용을 새로운 배열에 복사한다.
1.3 배열의 초기화
배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 배열을 사용하기 전에 따로 초기화를 해주지 않아도 되지만, 원하는 값을 저장하려면 각 요소(인덱스)마다 값을 지정해줘야 한다. 배열의 초기화 방법은 크게 세 가지 정도다.
1) 인반적인 방법(요소마다 값을 넣어주어야 한다)
① score[0] = 0; score[1] = 10; score[2] = 20; score[3 ]=30; score[4] = 40; score[5] = 50;
2) for문을 이용한 방법(일반적인 규칙이 존재할 때 주로 사용)
① for(int i = 0; i >= score.length; i++){
score[i] = i * 10;
}
배열명.length는 배열의 인덱스 길이에 대한 정보를 얻을 때 사용할 수 있다.
3) 주로 사용하는 방법(배열의 생성과 초기화를 한번에)
① int[] score = {10, 20, 30, 40, 50};
- 위 괄호{} 안에 저장할 값들을 쉼표로 구분하여 나열하면 []안에 배열의 길이는 적지 않는다. 왜냐하면 괄호{} 안에 적힌 값의 개수에 의해 배열의 길이가 자동적으로 결정되기 때문이다.
- new 타입[]를 생략하여 코드를 더 간단하게 할 수도 있다.
- 단 배열의 선언과 생성을 따로 하는 경우에는 생략할 수 없다.
- 만약 괄호{} 안에 아무것도 넣지 않으면 길이가 0인 배열이 생성된다.
- 참조변수는 null이지만, 배열을 가리키는 참조변수는 null대신 길이가 0인 배열로 초기화하기도 한다.
Arrays.toString(배열명) : 메소드를 사용하면 여러가지 방면에서 출력할 때 활용이 가능하다. 이 메소드는 배열의 모든 요소를 '[첫번째 요소, 두번째 요소, 세번째 요소, ...]'와 같은 형식의 문자열로 만들어서 반환하는 기능을 제공한다.
Arrays.toString()메소드의 사용 예제)
public class arrayEx1 {
public static void main(String[] args) {
int[] iArr = {100, 90, 84, 70, 60};
① System.out.println(iArr); //→ [I@7852e922이란 값이 출력된다.
② System.out.println(Arrays.toString(iArr)); //→ [100, 90, 84, 70, 60]이 출력된다.
}
}
만약 참조변수의 주소가 출력될 것이라 생각했다면 옳은 생각이다. 다만 배열의 주소가 있는 그대로 출력되는 것이 아니라 '타입@주소'의 형식으로 출력된다. 여기서 'I'는 1차원 int배열이란 의미이고, '@' 뒤에 나오는 16진수는 배열의 주소인데 실제 주소가 아닌 내부 주소다. 예외적으로 char타입의 배열은 각 요소가 구분자 없이 그대로 출력되는데, 이것은 println메소드가 char 배열일 때만 이렇게 동작하도록 작성되어 있다.
1.4 배열의 복사
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이 새로운 배열을 가리키게 된다.
글로 정리한 과정을 그림으로 보면 다음과 같다.
① int[] arr = new int[5];
② int[] tmp = new tmp[arr.length*2];
- 배열 arr의 길이인 arr.length의 값이 5이므로 길이가 10인 int배열 tmp가 생성되고, 배열 tmp의 각 요소는 int의 기본 값인 0으로 초기화된다.
③ for(int = i; i <arr.length; i++)
tml[i] = arr[i];
- for문을 이용해서 배열 arr의 모든 요소에 저장된 값을 하나씩 배열 tmp에 복사
④ arr = tmp;
참조변수 arr에 참조변수 tmp의 주소 값을 저장한다.
- arr의 값은 0x100에서 0x200으로 바뀌고, arr은 배열 tmp를 가리키게 된다.
⑤ 참조변수 arr과 tmp는 변수명만 다를뿐 0x200이라는 같은 주소의 배열을 가리키게 된다. 그리고 기존에 있던 arr이 가리키던 배열은 더 이상 사용할 수 없게 된다(가비지 컬렉터가 정리)
**배열은 참조변수를 통해서만 접근할 수 있기 때문에, 자신을 가리키는 참조변수가 없는 배열은 사용할 수 없다. 이렇게 쓸모 없어된 배열은 JVM의 가비지 컬렉터에 의해 자동적으로 메모리에서 제거된다.
2) System.arraycopy()를 이용한 배열의 복사
for문 대신 System클래스의 arraycopy()를 사용하면 보다 간단하고 빠르게 배열을 복사할 수 있다. for문은 배열의 요소 각각에 접근하여 복사하지만, arraycopy()는 지정된 범위의 값들을 한 번에 통째로 복사한다. 이는 각 요소들이 연속적으로 저장되어 있는 배열의 특성 때문에 가능한 것이다.
for문과의 비교
① for(int=0; i < num.length; i++) { newNum[i] = num[i]; }
② System.arraycopy(num, 0, newNum, 0, num.length);
→ num[0]에서 newNum[0]으로 num.length개의 데이터를 복사한다는 의미
'Java > Basic' 카테고리의 다른 글
2차원 배열, Arrays클래스 (0) | 2021.02.25 |
---|---|
String 배열 (0) | 2021.02.23 |
반복문(for, while, do-while) (0) | 2021.02.20 |
조건문(if, switch) (0) | 2021.02.19 |
연산자 (0) | 2021.02.18 |
댓글