배열 시작
학생의 점수를 출력하는 프로그램
package array;
public class Array1 {
public static void main(String[] args) {
int student1 = 90;
int student2 = 80;
int student3 = 70;
int student4 = 60;
int student5 = 50;
System.out.println("학생1 점수: " + student1);
System.out.println("학생2 점수: " + student2);
System.out.println("학생3 점수: " + student3);
System.out.println("학생4 점수: " + student4);
System.out.println("학생5 점수: " + student5);
}
}
변수를 선언하는 부분을 보면 학생 수가 증가함에 따라 `int`형 변수를 계속해서 추가해야 한다. 학생 수가 5명이면 `int`형 변수를 5개 선언해야 하고, 학생 수가 100명이라면 `int`형 변수를 100개 선언해야 한다. 결국 비슷한 변수를 반복해서 선언하는 문제가 발생한다.
반복문으로 해결할 수 있을 것 같지만, 점수를 출력하는 부분을 보면 변수의 이름이 다르기 때문에 반복문도 적용할 수 없다.
이렇게 같은 타입의 변수를 반복해서 선언하고 반복해서 사용하는 문제를 해결하는 것이 바로 배열이다.
배열의 선언과 생성
배열은 같은 타입의 변수를 사용하기 편하게 하나로 묶어둔 것이다.
package array;
public class Array1Ref1 {
public static void main(String[] args) {
int[] students; //배열 변수 선언
students = new int[5]; //배열 생성
//변수 값 대입
students[0] = 90;
students[1] = 80;
students[2] = 70;
students[3] = 60;
students[4] = 50;
//변수 값 사용
System.out.println("학생1 점수: " + students[0]);
System.out.println("학생2 점수: " + students[1]);
System.out.println("학생3 점수: " + students[2]);
System.out.println("학생4 점수: " + students[3]);
System.out.println("학생5 점수: " + students[4]);
}
}
1. 배열 변수 선언
- 배열을 사용하려면 `int[] students;`와 같이 배열 변수를 선언해야 한다.
- 일반적인 변수와 차이점은 `int[]`처럼 타입 다음에 대괄호(`[]`)가 들어간다는 점이다.
- 배열 변수를 선언한다고 해서 아직 사용할 수 있는 배열이 만들어진 것은 아니다.
2. 배열 생성
- 배열을 사용하려면 배열을 생성해야 한다.
- `new int[5]`라고 입력하면 오른쪽 그림과 같이 총 5개의 `int`형 변수가 만들어진다.
- `new`는 새로 생성한다는 뜻이고, `int[5]`는 `int`형 변수 5개라는 뜻이다. 따라서 `int`형 변수 5개를 다룰 수 있는 배열을 새로 만든다는 뜻이다.
- 앞서 `int student1`, `int student2` ... `int student3`까지 총 5개의 변수를 직접 선언했다. 배열을 사용하면 이런 과정을 한 번에 깔끔하게 처리할 수 있다.
베열과 초기화
- `new int[5]`라고 하면 총 5개의 `int`형 변수가 만들어진다. 자바는 배열을 생성할 때 그 내부값을 자동으로 초기화한다.
- 숫자는 `0`, `boolean`은 `false`, `String`은 `null`로 초기화된다.
3. 배열 참조값 보관
- `new int[5]`로 배열을 생성하면 배열의 크기만큼 메모리를 확보한다.
- `int`형을 5개 사용하면 `4byte * 5` → `20byte`를 확보한다.
- 배열을 생성하고 나면 자바는 메모리 어딘가에 있는 이 배열에 접근할 수 있는 참조값(주소)(`x001`)을 반환한다.
- 여기에서 `x001`이라고 표현한 것이 참조값이다. (실제로 `x001`처럼 표현되는 것은 아니고 이해를 돕기 위한 예시이다.)
- 앞서 생성한 배열 변수인 `int[] students`에 생성된 배열의 참조값(`x001`)을 보관한다.
- `int[] students` 변수는 `new int[5]`로 생성한 배열의 참조값을 가지고 있다.
- 이 변수는 참조값을 가지고 있다. 이 참조값을 통해 배열을 참조할 수 있다. 쉽게 이야기해서 참조값을 통해 메모리에 있는 실제 배열에 접근하고 사용할 수 있다.
- 배열을 생성하는 `new int[5]`자체에는 아무런 이름이 없다. 그냥 `int`형 변수를 5개 연속으로 만드는 것이다. 따라서 생성한 배열에 접근하는 방법이 필요하다. 따라서 배열을 생성할 때 반환되는 참조값을 어딘가에 보관해두어야 한다. 앞서 `int[] students`변수에 참조값(`x001`)을 보관해두었다. 이 변수를 통해서 이 배열에 접근할 수 있다.
이 부분을 풀어서 설명하면 다음과 같다.
int[] students = new int[5]; // 1. 배열 생성
int[] students = x001; //2. new int[5]의 결과로 x001 참조값 반환
students = x001 // 3. 최종 결과
참조값을 확인하고 싶다면 다음과 같이 배열의 변수를 출력해보면 된다.
System.out.println(students);
//[I@4617c264 @앞의 [I는 int형 배열을 뜻한다. @뒤에 16진수는 참조값을 뜻한다.
배열 사용
인덱스
배열은 변수와 사용법이 비슷한데, 차이점이 있다면 `[]`사이에 숫자 번호를 넣어주면 된다. 배열의 위치를 나타내는 숫자를 인덱스(index)라 한다.
//변수 값 대입
students[0] = 90;
students[1] = 80;
//변수 값 사용
System.out.println("학생1 점수: " + students[0]);
System.out.println("학생2 점수: " + students[1]);
배열은 0부터 시작한다.
`new int[5]`와 같이 5개의 요소를 가지는 `int`형 배열을 만들었다면 인덱스는 `0, 1, 2, 3, 4`가 존재한다.
여기서 주의해야 할 점이 있는데 인덱스는 0부터 시작한다는 것이다. 배열의 요소를 5개로 생성했지만, 인덱스는 0부터 시작한다. 따라서 사용 가능한 인덱스의 범위는 `0 ~ (n-1)`이 된다. 그래서 `student[4]`가 배열의 마지막 요소이다.
인덱스 허용 범위를 넘어설 때 발생하는 오류
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5 at array.Array1Ref1.main(Array1Ref1.java:14)
배열에 값 대입 & 읽기
배열에 값을 대입하든 배열의 값을 사용하든 간에 일반적인 변수와 사용법은 같다. 추가로 `[]`을 통해 인덱스만 넣어주면 된다.
students[0] = 90; //1. 배열에 값을 대입
x001[0] = 90; //2. 변수에 있는 참조값을 통해 실제 배열에 접근. 인덱스를 사용해서 해당 위치의 요소에 접근, 값 대입
// 1. 변수 값 읽기
System.out.println("학생1 점수: " + students[0]);
// 2. 변수에 있는 참조값을 통해 실제 배열에 접근. 인덱스를 사용해서 해당 위치의 요소에 접근
System.out.println("학생1 점수: " + x001[0]);
// 3. 배열의 값을 읽어옴
System.out.println("학생1 점수: " + 90);
배열을 사용하면 이렇게 참조값을 통해서 실제 배열에 접근하고 인덱스를 통해서 원하는 요소를 찾는다.
기본형 vs 참조형
자바의 변수 타입을 가장 크게 보면 기본형과 참조형으로 분류할 수 있다. 사용하는 값을 직접 넣을 수 있는 기본형, 그리고 방금 본 배열 변수와 같이 메모리의 참조값을 넣을 수 있는 참조형으로 분류할 수 있다.
- 기본형(Primitive Type): `int`, `long`, `double`, `boolean`처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입
- 참조형(Reference Type): `int[] students`와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입. 객체나 클래스를 담을 수 있는 변수들도 모두 참조형이다.
배열은 왜 복잡하게 참조형을 사용할까?
기본형은 모두 사이즈가 명확하게 정해져있다.
int i; // 4byte
long l; // 8byte
double d; // 8byte
그런데 배열은 다음과 같이 동적으로 사이즈를 변경할 수 있다.
int size = 10000; // 사용자가 입력한 값을 넣었다고 가정해보자.
new int[size]; // 이 코드가 실행되는 시점에 배열의 크기가 정해진다.
- 기본형은 선언과 동시에 크기가 정해진다. 따라서 크기를 동적으로 바꾸거나 할 수는 없다. 반면에 배열과 같은 참조형은 크기를 동적으로 할당할 수 있다. 이런 것을 동적 메모리 할당이라 한다. 기본형은 선언과 동시에 사이즈가 정적으로 정해지지만, 참조형을 사용하면 이처럼 동적으로 크기가 변해서 유연성을 제공할 수 있다.
- 기본형은 사용할 값을 직접 저장한다. 반면에 참조형은 메모리에 저장된 배열이나 객체의 참조를 저장한다. 이로 인해 참조형은 더 복잡한 데이터 구조를 만들고 관리할 수 있다. 반면 기본형은 더 빠르고 메모리를 효율적으로 처리한다.
2차원 배열
2차원 배열은 행과 열로 구성된다.
2차원 배열은 `int[][] arr = new int[2][3]`와 같이 선언하고 생성한다. 그리고 `arr[1][2]`와 같이 사용하는데, 먼저 행 번호를 찾고, 그 다음에 열 번호를 찾으면 된다.
2차원 배열의 사용법은 `[]`가 하나 추가되는 것을 제외하고는 앞서본 1차원 배열과 같다.
향상된 for문
향상된 for문을 이해하려면 배열을 먼저 알아야 한다. 각각의 요소를 탐색한다는 의미로 for-each문이라고도 많이 부른다. 향상된 `for`문은 배열을 사용할 때 기존 `for`문보다 더 편리하게 사용할 수 있다.
향상된 for문 정의
for (변수 : 배열 또는 컬렉션) {
// 배열 또는 컬렉션의 요소를 순회하면서 수행할 작업
}
- 단축키: iter
package array;
public class EnhancedFor1 {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
//일반 for문
for (int i = 0; i < numbers.length; i++) {
int number = numbers[i];
System.out.println(number);
}
//향상된 for문, for-each문
for (int number : numbers) {
System.out.println(number);
}
//for-each문을 사용할 수 없는 경우, 증가하는 index 값 필요한 경우
for (int i = 0; i < numbers.length; i++) {
System.out.println("number" + i + "번의 결과는: " + numbers[i]);
}
}
}
'Java' 카테고리의 다른 글
[Java/김영한] 클래스와 데이터 (0) | 2024.09.06 |
---|---|
[Java/김영한] 메서드 (0) | 2024.08.15 |
[Java/김영한] 스코프, 형변환 (0) | 2024.08.13 |
[Java/김영한] 반복문 (0) | 2024.08.12 |
[Java/김영한] 조건문 (0) | 2024.08.12 |