배열은 크게 1차원 배열고 ㅏ다차원 배열, 두가지로 나뉠 수 있습니다.
배열을 활용하면 모든 값을 하나의 변수에 넣을 수 있습니다.
int[] odd = {1,3,5,7,...,99};
배열이 가진 각각의 값을 요소
또는 원소
라고 합니다. 배열의 요소에 접근할 때에는 요소의 순서(index)
를 활용합니다. 배열이름[인덱스]
로 배열의 각각의 값에 접근할 수 있습니다.
// 크기 할당 & 초기화 없이 선언하는 경우
int[] arr;
int arr[];
위의 예시에서 arr
은 배열의 시작위치만 저장하고 있는 변수 입니다. 아직 배열이 만들어 지지는 않았습니다. (참조 타입: 변수에 저장될 때, 주소 값이 저장됩니다.)
//선언과 동시에 초기화
int[] arr1 = new int[5]; // arr -> {0, 0, 0, 0, 0}
// 배열의 요소에 값을 저장하지 않으면 각 요소는 해당 타입의 기본값으로 자동으로 채워 집니다.
// 선언 후 초기화
int[] arr;
arr = new int[5]; // arr -> {0, 0, 0, 0, 0}
// 배열의 요소에 값을 저장하지 않으면 각 요소는 해당 타입의 기본값으로 자동으로 채워 집니다.
//선언과 동시에 값을 넣어 초기화
int[] arr = {1,2,3,4,5};
int[] arr = new int[] {1,2,3,4,5}; // arr -> {1,2,3,4,5}
배열이름.length
로 배열이 가진 요소의 갯수, 배열의 길이를 알 수 있습니다.
int[] arr = new int[5];
arr.length //5
배열의 길이는 배열의 마지막 인덱스에 +1
한 것과 동일합니다.(인덱스가 0부터 시작하기 때문)
배열A의 요소로 배열B,배열C,배열D가 존재 함으로써 배열안의 배열로 종 횡을 이루면 2차원 배열이 됩니다. 만약 요소인 배열인 배열B안에 또다른 배열E가 존재한다면 3차원 등으로 차원이 올라갑니다.
//크기 할당 및 초기화 없이 선언만 하는 경우
int[][] arr;
// 3차원 배열을 선언하는 경우
int[][][] arr;
// 선언과 동시에 배열의 크기를 지정한 경우
int[][] arr = new int[2][3];
int[][] arr;
arr = new int[2][3];
// 배열은 아래와 같이 초기화가 됩니다.
// {
// {0, 0, 0},
// {0, 0, 0}
// }
// 선언과 동시에 값을 넣어 초기화하는 경우
int[][] arr = {{1,3,5},{2,4,6}};
int[][] arr = new int[][] {{1,3,5},{2,4,6}};
// 배열은 아래와 같이 초기화가 됩니다.
// {
// {1, 3, 5},
// {2, 4, 6}
// }
new키워드와 지정된 크기를 사용해서 배열을 선언하면 먼저 지정된 크기만큼 0으로 초기화된 배열을 만들고 그 내부에 두번째 크기만큼 0으로 초기화된 상태의 배열이 만들어 집니다. 첫번째 배열에서 두번째로 지정된 배열의 참조값으로 두번째 배열에 접근할 수 있습니다.
위의 사진에서 밖의 배열은 크기를 지정해 줘야하지만 안의 배열은 크기를 지정할 필요가 없는 것을 알 수 있습니다.(배열의 크기를 지정하지 않아도 선언 가능합니다.) 따라서 안의 배열들으 ㅣ크기를 모두 동일하게 만들 필요 없이 제각각으로 선언할 수 있습니다.
1부터 100까지의 소수를 제외한 수를 저장하는 2차원 배열을 만든다고 가정하겠습니다. 밖의 배열은 10의자리, 안의 배열은 1의자리 입니다. 각 10의 단위마다 소수의 갯수가 다르므로 안의 배열의 크기는 제각각입니다.
int[][] arr = new int[10][]
첫번째 배열에는 10이라는 크기를 초기화했지만 그 공간 안에 넣을 배열들은 초기화 하지않고 참조변수를 담을 공간만 할당하였습니다. 메모리가 낭비되는 것을 방지할 수 있습니다.
배열은 요소의 순서(index)
가 있는 값의 묶음입니다. 마찬가지로 문자열도 순서가 있는 값의 묶음입니다. 문자열 배열을 선언하고 초기화 할 수 있습니다.
//선언 후 각 배열에 값을 넣어 초기화
String[] str = new String[3];
str[0] = "Hello";
str[1] = "Java";
str[2] = "world";
//선언과 동시에 값을 넣어 초기화
String[] str = new String[] {"Hello","Java","world"};
String[] str = {"Hello","Java","world"}; // new String[] 생략 가능
//한번에 만들기
String str = "Hello Java World";
문자와 문자열을 변수에 담을 때 주의 사항
''
로 묶지만, 문자열은 ""
로 묶어야 합니다.배열에는 같은 타입의 값들이 묶음으로 담겨 있습니다. 따라서 그 값들을 꺼내 쓰려면 알아야 할 것이 있습니다.
배열의 각 요소에 접근하기 위해선 인덱스
를 사용합니다. 인덱스는 1이 아닌 0
부터 시작합니다.(길이가 1 더 큰 이유)
int[] arr = {1, 2, 3, 4, 5};
System.out.println(arr[2]); // 숫자 3이 출력
arr[2] = 6;
System.out.println(arr[2]); // 숫자 6이 출력
int[] arr = {1,2,3,4,5};
System.out.println(arr.length);
//2차원 배열
int[][] arr {{1,2,3},{4,5};
System.out.printfln(arr.length); // 숫자 2가 출력
System.out.printfln(arr[0].length); // 숫자 3이 출력
System.out.printfln(arr[1].length); // 숫자 2가 출력
for 문으로 배열을 탐색
int[] arr = {1, 2, 3, 4, 5};
// for문을 사용한 탐색 경우
for(int i = 0; i < arr.length; i++){
System.out.println(arr[i]);
// for-each문을 사용한 탐색 경우
for (int num: arr) {
System.out.println(num);
}
주의해야 할점은 for문
은 값을 읽어들이는 것, 할당하는 것 둘다 가능하지만, for-each문
은 값을 읽어들이는 것만 가능합니다.
int[] arr1 = {1, 2, 3, 4, 5};
// 일반적인 for문은 arr1이 가진 요소의 값을 재 할당할 수 있습니다.
for(int i=0;i<arr1.length;i++){
arr1[i] += 1;
}
// arr1 출력 결과 : {2,3,4,5,6}
for(int i=0;i<arr1.length;i++){
System.out.printf("%d",arr1[i]);
}
int[] arr2 = {1, 2, 3, 4, 5};
// for each문은 arr2이 가진 요소의 값을 재할당 할 수 없습니다.
for(int num: arr2){
num += 1; // arr2 배열에는 변화x
}
// arr2 출력 결과 : {1, 2, 3, 4, 5}
for (int num: arr2) {
System.out.printf("%d", num);
}
흔히 배열을 복사한다고 가정하면 for문
으로 요소를 하나씩 복사할 것입니다. 하지만 for문이나 while문 등 반복문을 사용하지 않고 복사를 제공하는 메서드 3가지가 존재합니다.
Arrays.copyOf(원본,종료index)
는 배열의 시작부터 종료index까지 배열의 복사합니다.
int[] origin = {1,2,3,4,5}
int[] coppied = Arrays.copyOf(origin,3); // copied = {1,2,3}
int[] coppied = Arrays.copyOf(origin,origin.length); // copied = {1,2,3,4,5}
Arrays.copyOfRange(배열,from,to)
는 배열의 from 부터 to 까지의 배열을 복사합니다.
int[] origin = {1,2,3,4,5}
int[] coppied = Arrays.copyOfRange(origin,0,origin,length); // copied = {1,2,3,4,5}
int[] coppied = Arrays.copyOf(origin,1,4); // copied = {2,3,4}
System.arraycopy(원본,start,사본,start,크기)
는 따로 반환하는 배열 없이 원본의 요소들을 복사하여 사본에 저장합니다. 원본과 사본은 각각 시작위치인 start를 가지며 얼마만큼 복사할 것인지 크기를 지정해야 합니다.
int[] origin = {1,2,3,4,5}
int[] coppied = new int[5] //{0,0,0,0,0}
System.arraycopy(origin,0,coppied,0,origin.length); // copied = {1,2,3,4,5}
System.arraycopy(origin,1,coppied,1,3); // copied = {2,3,4}
이미 배열을 알고 있었지만 복사 관련한 메서드는 정말 큰 도움이 되었다!