배열이란 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것이다. 서로 다른 타입의 변수들로 구성된 배열은 만들 수 없다. 변수와 달리 배열은 각 저장공간이 연속적으로 배치되어있다.
배열의 선언과 생성
배열을 선언하는 방법은 원하는 타입의 변수를 선언하고 대괄호[]를 붙이거나 타입과 변수명을 선언한 뒤 대괄호를 붙이면 된다.
int[] arr; // 타입을 선언한 뒤 대괄호[]를 붙이거나
int arr[]; // 타입과 변수명을 선언한 뒤 대괄호[]를 붙이면 된다.
배열을 선언하는 것은 배열을 다루기 위한 참조변수를 위한 공간이 만든 것이다. 값을 저장할 수 있는 공간을 만들기 위해 배열을 생성해야 한다. 배열을 생성할 때는 연산자 'new'와 함께 배열의 타입과 길이를 지정해야한다.
int[] arr; //배열을 다루기 위한 참조변수 선언
arr = new int[5]; //실제 저장공간을 생성
배열의 길이와 인덱스
생성된 배열 각각의 저장공간을 '배열의 요소'라고 하며, 배열이름[인덱스]의 형식으로 배열의 요소에 접근한다. 인덱스는 배열의 요소마다 붙여진 일련변호로 각각의 요소를 구별하는데 사용한다. 인덱스의 범위는 0부터 배열길이-1까지이다. 인덱스의 범위를 벗어난 값을 인덱스로 사용할 경우, 변수의 값은 실행시 주입되므로 컴파일러가 인덱스의 범위를 확인할 수 없다. 유효하지 않은 값을 인덱스로 사용하면 실행시 'ArrayIndexOutOfBoundsException'이 발생한다
배열의 길이는 배열의 요소의 개수로, 값을 저장할 수 있는 공간의 개수와 같다. 배열의 길이는 int범위의 양의 정수(0도 포함)이어야 한다.
자바에서는 JVM이 모든 배열의 길이를 별도로 관리하며, '배열이름.length'를 통해서 배열의 길이에 대한 정보를 얻을 수 있다. 배열은 한번 생성하면 길이를 변경할 수 없어 배열이름은 배열이름.length는 상수이다.
배열을 선언하면 길이를 변경할 수 없다. 배열의 길이를 변경하는 방법은 더 큰 배열을 새로 생성하고 기존의 배열 내용을 새로운 배열에 복사한다
배열의 초기화
배열은 생성 뒤 자신의 타입에 해당하는 기본값으로 초기화된다. 원하는 값을 저장하려면 각 요소마다 값을 지정해주면 된다. for문을 사용하는 것이 좋지만 for문을 사용하려면 값에 일정한 규칙이 있어야 한다.
int[] arr = new int[]{1, 2, 3, 4, 5}; //배열의 선언과 생성을 동시에 할 수 있다.
int[] arr = {1, 2, 3, 4, 5}; //new int[]를 생략할 수 있다.
int[] arr;
arr = {1, 2, 3, 4, 5}; //배열의 선언과 생성을 따로 하는 경우 new int[]를 생략할 수 없어 에러 발생한다.
arr = new int[]{1, 2, 3, 4, 5};
int[] arr = new int[0]; //모두 길이가 0인 배열을 생성한다.
int[] arr = new int[]{};
int[] arr = {};
배열에 저장된 값을 출력할 때도 배열의 인덱스를 이용하여 for문을 사용하면 된다. 더 간단한 방법은 'Arrays.toString(배열이름)'메소드를 사용하는 것이다. 위 두 가지 방법이 아니라 변수명으로 배열을 바로 출력하면 '배열의 타입' +@ + '참조변수의 주소'를 출력한다. 예외로 char배열은 println메소드로 출력하면 각 요소가 구분자 없이 그대로 출력한다.
배열의 복사
배열은 한번 생성하면 그 길이를 변경할 수 없어 저장공간이 더 많이 필요하다면 큰 배열을 새로 만들고 이전 배열의 요소를 복사해야 한다. 배열을 복사하는 것은 비용이 많이 들기 때문에 처음부터 배열의 길이를 넉넉하게 잡아야 한다. 하지만 배열의 크기가 너무 크다면 메모리를 낭비하게 되므로 기존 크기의 두 배로 생성하는 것이 좋다.
배열의 요소 타입이 String인 경우에도 기본형 타입의 배열 선언과 동일한 방법으로 배열을 생성한다. 참조형 변수의 기본값은 null로, 각 요소의 값도 null로 초기화 된다.
자료형
기본값
boolean
false
char
'\u0000'
byte, short, int
0
long
0L
float
0.0f
double
0.0d 또는 0.0
참조형 변수
null
String배열의 초기화
String배열의 초기화 역시 int과 동일한 방식으로 각 문자열에 직접 값을 지정하거나 괄호{}를 사용하여 초기화할 수 있다.
String[] num = new String[3];
num[0] = "One";
num[1] = "Two";
num[2] = "Three"; //배열의 요소마다 값을 직접 지정하거나
String[] num = new String[]{"One", "Two", "Three"}; //괄호를 사용하여 지정할 수 있다.
String[] num = {"One", "Two", "Three"}; //new String[]은 생략할 수 있다.
char배열과 String클래스
문자열을 저장할 때 사용하는 String타입은 char배열과 같다. String클래스는 char 배열에 여러가지 기능이 포함된 메소드를 추가하여 확장한 것이다. char배열과 String클래스의 차이점은 char배열은 내용을 변경할 수 있지만, String 객체는 내용을 변경할 수 없고 읽을 수만 있다. String 객체를 변경하고자 한다면 StringBuffer클래스를 이용하면 된다.
문자열에서 해당 범위(from~to)에 있는 문자열을 반환한다. to는 범위에 포함되지 않는다.
boolean equals(Object obj)
문자열의 내용이 obj와 같은지 확인한다. 같으면 결과는 true, 다르면 false가 된다.
char[] toCharArray()
문자열을 문자배열(char[])로 변환해서 반환한다.
커맨드 라인을 통해 입력받기
사용자로부터 값을 입력받을 때, Scanner클래스의 nextLine()외에 다른 방법이 있다. 프로그램을 실행할 때 클래스 이름 뒤에 공백문자로 구분하여 여러 개의 문자열을 프로그램에 전달하는 것이다. 이를 커맨드라인을 이용하는 입력 방법이라 한다. 커맨드 라인을 통해 입력한 문자열은 공백문자로 구분하여 클래스의 메인 메소드의 매개변수(args)로 전달된다.
아래와 같이 코드를 작성했다. 메인 메소드의 매개변수 args를 입력받아 그 길이가 0일 때와 0보다 클 때의 출력을 다르게 설정했다. 터미널에서 컴파일하고 실행한 결과를 볼 수 있다.
public class Hello {
public static void main(String[] args) {
//커맨드 라인을 통해 전달받은 매개변수가 없을 때
if(args.length==0) {
System.out.println("입력값이 없습니다.");
System.exit(0);
}else {
//커맨드 라인을 통해 전달받은 매개변수의 수만큼 반복
for(int n=1; n<=args.length; n++){
System.out.println("HELLO!");
}
}
}
}
다차원 배열
2차원 배열의 선언과 인덱스
2차원 배열을 선언하는 방법은 1차원 배열을 선언하는 방법과 동일하다. 괄호[]를 더 붙이면 된다.
int[][] arr;
int arr[][];
int[] arr[];
2차원 배열의 인덱스는 2차원 배열이 행과 열로 구성되어 있기 때문에 각각 존재한다.
int[][] arr = new int[4][3];
2차원 배열의 초기화
2차원 배열을 초기화할 때에는 {}괄호를 한 번 더 사용하여 행을 구분해준다. 위 그림과 같은 4행 3열의 배열의 각 요소값을 초기화해주기위해서는 각각 아래의 위치에 값을 넣어야 한다.