배열
- 같은 타입의 여러 변수를 하나로 묶어 사용
- e.g.) int nNum1, nNum2, nNum3; ➡ int[] nNum;
배열의 선언과 생성
- e.g.) int[] nNum = new int[3];
- 배열의 선언은 배열을 다루기 위한 참조변수(nNum) 선언
- 배열의 생성(new)과 함께 배열의 저장공간 생성(int[3])
- 배열은 인덱스가 생성되며 번호는 0번부터 시작(nNum[0], nNum[1], nNum[2])
- 참조변수는 인덱스의 0번 주소를 참조(nNum ➡ int nNum[0] , int nNum[1], int nNum[2])
배열의 저장구조
- 참조변수는 Stack영역에 생성되며 Heap영역에 있는 인덱스의 0번 주소를 참조
- 참조변수의 크기는 주소를 담는 공간으로 OS비트 x32(4byte), x64(8byte) 에 따라 다름
- 배열은 따로 초기화 하지 않아도 JVM(Java Virtual Machine)이 지정한 기본값으로 배열 초기화
배열 선언과 초기화
배열 초기화 종류
- 인덱스를 이용한 초기화
- 반복문을 이용한 초기화
- 선언과 동시에 초기화
배열 크기 변경
- 한 번 지정된 크기는 실행하는 동안 변경 불가
- 배열은 연속적으로 공간이 지정되는데 추가했을 경우 그 뒤에 데이터가 존재할 수 있기 때문에 불가
- 다시 배열 크기를 지정하여 새로 생성하여 공간 재배치
- heap 영역에 참조되지 않는 공간은 GC(Garbage Collection)가 메모리에서 제거
배열의 선언과 생성 방법 2가지
// 1번
타입[ ] 변수이름; // 배열의 선언, stack영역에 참조변수 생성
변수이름 = new 타입[길이]; // 배열 생성, heap영역에 배열의 길이 만큼 생성
// 2번
타입[ ] 변수이름 = new 타입[길이] // 배열의 선언과 생성
// 예제
// int형 배열 3개 생성
int[] nNum4 = new int[3]; // nNum4[0], nNum4[1], nNum4[2]
int nNum5[] = new int[3]; // nNum5[0], nNum5[1], nNum5[2]
배열 초기화 방법
// 인덱스를 이용한 초기화
nArr[0] = 1;
nArr[1] = 10;
// for문을 이용한 초기화
for(int i = 0; i < nArr.length; i++) {
nArr[i] = i;
}
// 선언과 동시에 초기화
int[] nArr1 = {};
int[] nArr2 = {1, 2, 3, 4, 5, 6, 7};
int[] nArr3 = new int[] {1, 2, 3, 4, 5, 6, 7}
String[] nArr4 = {'A', 'B', 'C'};
배열 사용 이유
- 생성과 초기화 즉, 생성과 관리가 빠르고 편리하다.
// int형 변수 100개 생성 후 초기화
int nNum1 = 1;
int nNum2 = 2;
int nNum3 = 3;
...
int nNum99 = 99;
int nNum100 = 100;
// int형 배열 100개 생성 후 초기화
int[] nArr = new int[100];
for(int i = 0; i <= nArr.length; i++) nArr[i] = i + 1;
배열 길이 확인
- .length를 사용하여 길이 확인
- 배열의 크기를 변경해도 조건식 등에 사용중인 코드를 변경하지 않아도 됨
public void method2() {
int[] nData = new int[5];
int tmp = nData.length;
System.out.println("nData Length: " + tmp);
}
출력물
nData Length: 5
배열 출력
- Arrays.toString()을 사용하여 배열의 모든 요소를 문자열로 출력
public void method2() {
int[] nData = {10, 20, 30, 40, 50}; // 배열 초기화
// 각 요소 출력
for(int i = 0 ; i < nData.length; i++) {
System.out.printf("nData[%d]: %d\n", i, nData[i]);
}
System.out.println();
// 배열 모든 요소를 문자열로 출력
System.out.printf("nData: " + Arrays.toString(nData));
}
출력물
nData[0]: 10
nData[1]: 20
nData[2]: 30
nData[3]: 40
nData[4]: 50
nData: [10, 20, 30, 40, 50]
참조변수의 주소, 자동 초기화 확인
public void method1() {
int[] nArr; // stack영역에 참조변수 nArr 생성
double[] dArr; // stack영역에 참조변수 dArr 생성
nArr = new int[3]; // heap영역에 int형 3개 크기만큼 생성
dArr = new double[3]; // heap영역에 double형 3개 크기만큼 생성
System.out.println("nArr Address: " + nArr); // stack영역 참조변수 nArr의 주소값
System.out.println("dArr Address: " + dArr);
System.out.println();
System.out.println("nArr Address: " + nArr.hashCode()); // heap영역 nArr[0]의 16진수 주소값을
System.out.println("dArr Address: " + dArr.hashCode()); // 10진수로 변환하여 반환
System.out.println();
for(int i = 0; i < nArr.length; i++) { // .length를 사용하여 배열의 크기 확인
System.out.printf("nArr[%d]: %d\n", i, nArr[i]);
}
System.out.println();
for(int i = 0; i < dArr.length; i++) { // 배열의 인덱스는 0부터 시작이므로 '<' 사용
System.out.printf("dArr[%d]: %f\n", i, dArr[i]);
}
}
출력물
nArr Address: [I@4926097b
dArr Address: [D@39ed3c8d
nArr Address: 1227229563
dArr Address: 971848845
nArr[0]: 0
nArr[1]: 0
nArr[2]: 0
dArr[0]: 0.000000
dArr[1]: 0.000000
dArr[2]: 0.000000
배열 크기 변경
int nArr = new int[3]
System.out.println("nArr Length: " + nArr.length);
System.out.println("nArr Address: " + nArr);
nArr = new int[5]; // 기존에 참조하고 있던 연결(int[3])이 끊기고 새로운 배열(int[5])을 참조
System.out.println("nArr Length: " + nArr.length);
System.out.println("nArr Address: " + nArr);
출력물
nArr Length: 3
nArr Address: [I@4926097b
nArr Length: 5
nArr Address: [I@47f37ef1
과일이름 입력 받아 출력
public void method2() {
String[] szFruit = new String[3];
Scanner s = new Scanner(System.in);
for(int i = 0; i < szFruit.length; i++) {
System.out.printf("Insert Fruit: ");
szFruit[i] = s.nextLine();
}
System.out.println();
for(int i = 0; i < szFruit.length; i++) {
System.out.printf("szFruit[%d] Name: %s\n", i, szFruit[i] );
}
}
출력물
Insert Fruit: 사과
Insert Fruit: 바나나
Insert Fruit: 블루베리
szFruit[0] Name: 사과
szFruit[1] Name: 바나나
szFruit[2] Name: 블루베리