배열
1. 배열
배열은 같은 타입의 데이터를 연속된 공간에 나열하고, 나열된 각 데이터에 인덱스를 부여해놓은 자료구조이다.
배열의 인덱스는 데이터를 저장하거나 불러올 때 사용되며,
인덱스는 0부터 시작한다.
2. 배열 변수 선언
배열을 사용하기 위해서는 배열 타입의 변수를 선언해야 한다.
- 타입[] 변수명;
- 타입 변수명[];
배열 변수 또한 참조 변수이므로 스택에 생성되고, 힙 영역에 존재하는 배열 객체를 참조하게 된다.
배열 변수도 null 값을 통해 초기화 할 수 있으며, 다른 참조 변수와 마찬가지로 이 경우에 배열 변수는 사용할 수 없다.
3. 배열 객체 생성(초기화)
배열 객체는 데이터 목록을 직접 이용하거나, new 연산자를 통해 배열 크기를 할당해주는 방법이 있다.
1) 데이터 목록으로 배열 객체 생성
- 타입[] 변수 = {값0, 값1, 값2, ... , 값n};
위의 실행문 처럼 배열 객체를 생성할 수 있다.
중괄호는 중괄호에 포함되어있는 데이터를 갖는 배열 객체를 힙 영역에 생성하고,
그 배열 객체의 번지를 해당 배열 변수에 리턴한다.
public class ArrayCreateByValueList {
public static void main(String[] args) {
int[] scores = {83, 90, 87};
System.out.printf("scores[0] : %d\n", scores[0]);
System.out.printf("scores[1] : %d\n", scores[1]);
System.out.printf("scores[2] : %d\n", scores[2]);
int sum = 0;
for(int i = 0; i < 3; i++) {
sum += scores[i];
}
System.out.printf("총합: %d\n", sum);
double arg = (double) sum / 3;
System.out.printf("평균: %f\n", arg);
}
}
값의 목록으로 배열 객체를 생성할 때 주의할 점이 있는데
배열 변수를 먼저 선언한 후에는 데이터 목록을 통해 배열 객체 생성이 안된다는 것이다.
이런 경우에는 아래와 같이 new 연산자를 통해 배열 객체를 생성해야한다.
- 변수 = new 타입[] {값0, 값1, 값2, ... , 값n};
public class ArrayCreateByValueListExample2 {
public static void main(String[] args) {
int[] scores;
scores = new int[] {83, 90, 87}; //배열변수를 먼저 선언했을 경우, new 연산자를 통해 배열을 생성해야한다.
int sum1 = 0;
for(int i = 0; i < 3; i++) {
sum1 += scores[i];
}
System.out.println("총합: " + sum1);
int sum2 = add(new int[] {83, 90, 87});
System.out.println("총합: " + sum2);
}
public static int add(int[] scores) {
int sum = 0;
for(int i = 0; i < 3; i++) {
sum += scores[i];
}
return sum;
}
}
2) new 연산자로 배열 객체 생성
배열에 저장하고 싶은 데이터는 정해지지 않았지만, 필요한 배열의 길이는 알고 있을 때
new 연산자를 통해 배열 객체를 생성할 수 있다.
- 타입[] 변수 = new 타입[길이];
위에서 언급했던 것 처럼 배열 변수를 먼저 선언한 후에도
new 연산자를 통해 배열 객체를 생성할 수 있다.
- 타입[] 변수;
- 변수 = new 타입[길이];
생성된 배열 객체의 각 인덱스 값을 아래와 같이 변경할 수 있다.
- 변수[n] = 변경 값;
public static void main(String[] args) {
int[] arr1 = new int[3]; //new를 통해 빈 배열을 생성하여 배열 변수를 초기화할 때, int 배열은 0이 초기값으로 사용된다.
for(int i = 0; i < 3; i++) {
System.out.printf("arr1[%d]: %d\n", i, arr1[i]);
}
arr1[0] = 10;
arr1[1] = 20;
arr1[2] = 30;
for(int i = 0; i < 3; i++) {
System.out.printf("arr1[%d]: %d\n", i, arr1[i]);
}
double[] arr2 = new double[3]; //new를 통해 빈 배열을 생성하여 배열 변수를 초기화할 때, double 배열은 0.0이 초기값으로 사용된다.
for(int i = 0; i < 3; i++) {
System.out.printf("arr2[%d]: %f\n", i, arr2[i]);
}
arr2[0] = 0.1;
arr2[1] = 0.2;
arr2[2] = 0.3;
for(int i = 0; i < 3; i++) {
System.out.printf("arr2[%d]: %f\n", i, arr2[i]);
}
String[] arr3 = new String[3]; //new를 통해 빈 배열을 생성하여 배열 변수를 초기화할 때, String 배열은 null이 초기값으로 사용된다.
for(int i = 0; i < 3; i++) {
System.out.printf("arr3[%d]: %s\n", i, arr3[i]);
}
arr3[0] = "1월";
arr3[1] = "2월";
arr3[2] = "3월";
for(int i = 0; i < 3; i++) {
System.out.printf("arr3[%d]: %s\n", i, arr3[i]);
}
}
}
4. 다차원 배열
행과 열로 구성된 다차원 배열 구성할 수 있다.
아래의 실행문은 2행, 3열의 배열을 생성한다.
- int[][] scores = new int[2][3];
위의 실행문은 힙 영역에 3개의 배열 객체를 생성한다.
첫번째는 행, 즉 2의 길이를 가진 int 배열 객체를 생성한다. (A)
두번째는 행의 첫번째 인덱스에 대한 3의 길이를 가진 배열 객체를 생성한다. (B)
세번째는 행의 두번째 인덱스에 대한 3의 길이를 가진 배열 객체를 생성한다. (C)
만약 scores[0][0]의 데이터를 불러온다면
먼저 scores는 A 객체를 참조하고, 다시 A 객체는 B 객체를 참조한다.
다차원 배열의 길이는 아래와 같이 불러올 수 있다.
- A 배열 객체: scores.length;
- B 배열 객체: scores[0].length;
- C 배열 객체: scores[1].length;
그리고 다차원 배열의 경우, 수학의 행렬 처럼 사각형일 수도 있지만, 계단식 구조로 생성될 수도 있다.
아래의 실행문을 보면
- int[][] scores = new int[2][];
- scores[0] = new int[2];
- scores[1] = new int[3];
첫번째 실행문에서 scores 변수는 2행과 n열을 가진 다차원 배열 변수로 초기화되었다.
두번째 실행문에서 행의 첫번째 인덱스에 대해 2의 길이를 가진 배열 객체를 생성한다.
세번째 실행문에서 행의 두번째 인덱스에 대해 3의 길이를 가진 배열 객체를 생성한다.
결과적으로 2행, 그리고 각 행에 대해 열의 길이가 다른 계단식 구조의 배열이 생성되었다.
또 다차원 배열 또한 데이터 목록을 통해 생성 될 수 있다.
- 타입[][] 변수 = { {값1-1, 값1-2}, {값2-1, 값2-2, 값2-3} };
내부 중괄호의 수는 행의 수를 의미하며, 각 내부 중괄호 안에 있는 데이터의 값은 해당하는 행의 열의 수를 말한다.
public class ArrayInArrayExample {
public static void main(String[] args) {
int[][] mathScores = new int[2][3];
for(int i = 0; i < mathScores.length; i++) {
for(int k = 0; k < mathScores[i].length; k++) {
System.out.println("mathScores[" + i + "][" + k + "]=" + mathScores[i][k]);
}
}
System.out.println();
int[][] englishScores = new int[2][];
englishScores[0] = new int[2];
englishScores[1] = new int[3];
for(int i = 0; i < englishScores.length; i++) {
for(int k = 0; k < englishScores[i].length; k++) {
System.out.println("englishScores[" + i + "][" + k + "]=" + englishScores[i][k]);
}
}
System.out.println();
int[][] javaScores = { {95, 80}, {92, 96, 80} };
for(int i = 0; i < javaScores.length; i++) {
for(int k = 0; k < javaScores[i].length; k++) {
System.out.println("javaScores[" + i + "][" + k + "]=" + javaScores[i][k]);
}
}
}
}
5. 배열 복사
배열 복사는 for문 또는 System.arraycopy() 메소드를 통해 처리할 수 있다.
아래는 for문을 통해 배열을 복사하는 코드이다.
public class ArrayCopyByForExample {
public static void main(String[] args) {
int[] oldIntArray = {1, 2, 3};
int[] newIntArray = new int[5];
for(int i = 0; i < oldIntArray.length; i++) {
newIntArray[i] = oldIntArray[i];
}
for(int i = 0; i < newIntArray.length; i++) {
System.out.print(newIntArray[i] + ", ");
}
}
}
System.arraycopy() 메소드의 사용법은 다음과 같다.
- System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
src는 원본 배열
srcPos는 원본 배열에서 복사할 시작 인덱스
dest는 새 배열
destPos는 새 배열에서 붙여넣을 시작 인덱스
length는 복사할 데이터 개수
public class ArrayCopyExample {
public static void main(String[] args) {
String[] oldStrArray = {"java", "array", "copy"};
String[] newStrArray = new String[5];
System.arraycopy(oldStrArray, 0, newStrArray, 0, oldStrArray.length);
for(int i = 0; i < newStrArray.length; i++) {
System.out.print(newStrArray[i] + ", ");
}
}
}
6. 향상된 for문
자바에는 배열이나 컬렉션에 대한 반복을 쉽게 처리하기 위한 for문이 제공된다.
이러한 for문에는 조건식과 증감식이 존재하지 않으며,
배열의 각 데이터를 저장할 변수 선언문, :, 배열을 작성한다.
- for(int score : scores) { ... };
이 향상된 for문의 실행 흐름은 다음과 같다.
배열 변수 scores가 score에 저장할 데이터를 갖고 있는지 확인한다.
데이터를 갖고 있을 경우 score에 해당 데이터를 저장한다.
중괄호 내부의 실행문을 실행한다.
scores에 그 다음 데이터가 존재하는지 확인한다. 데이터가 존재할 경우 위와 같이 반복하고, 없을 경우 for문을 종료한다.
public class AdvancedForExample {
public static void main(String[] args) {
int[] scores = {95, 71, 84, 93, 87};
int sum = 0;
for (int score : scores) {
sum = sum + score;
}
System.out.println("점수 총합: " + sum);
double avg = (double) sum / scores.length;
System.out.println("점수 평균 = " + avg);
}
}
출처: 혼자 공부하는 자바(신용권)