본 글은 [자바의 정석 3판 - 남궁성] 에 있는 5장 배열 파트와 자바의 정석 유튜브(남궁성의 정석코딩 - YouTube)에서 5장 배열 파트를 보고 요약한 글입니다.
배열이란
배열은 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것
배열은 각 저장 공간이 연속적이고 하나하나 붙어 있다.
아래의 abc 변수는 배열을 다루는 데 필요한 참조변수일 뿐 값을 저장하기 위한 공간은 아니다.
즉, 배열은 기본형과 같은 순수 값을 저장하는 것이 아닌 주소값을 저장한다.
int[] abc = new int[5];
배열의 선언과 생성
배열의 선언 - 배열을 다루기 위한 참조변수 선언
배열을 선언하는 방법
선언방법 | 선언 예 |
타입[ ] 변수이름; | String[ ] age; char[ ] number; |
타입 변수이름 [ ]; | String age[ ]; char number[ ]; |
타입[ ] 변수이름; // 배열을 선언(배열을 다루기 위한 참조변수 선언)
변수이름 = new 타입[길이]; // 배열을 생성(실제 저장공간을 생성)
int[] score; // int타입의 배열을 다루기 위한 참조변수 score선언
score = new int[5]; // int타입의 값 5개를 저장할 수 있는 배열 생성
int[ ] score; 변수를 선언하면 저장공간이 생기고 해당 저장공간의 이름이 score가 된다.
score = new int[5];를 하면 score의 저장공간이 5개가 생기고 score는 해당 저장공간의 주소를 담는다.
배열의 인덱스
배열의 인덱스 - 각 요소(저장공간)에 자동으로 붙는 일련번호
배열의 요소 - 배열 각각의 저장공간
인덱스의 범위 - 0부터 '배열길이 -1'까지
아래의 new int[숫자] 여기서의 숫자는 배열의 길이가 온다. 배열의 요소를 5개 만들고 싶으면 new int[5]이다.
만약 여기서 내가 배열의 인텍스 네번째에 값을 넣고 싶으면 score[3]=100; 적으면 된다. 이때 숫자 3는 배열의 인덱스이다.
int[] score = new int[5] // 배열의 길이는 5개이고 인덱스는 0~4까지 있다.
만일 아래와 같이 괄호[ ] 안에 수식이 포함된 경우, 이수식이 먼저 계산된다. 그래야만 배열의 몇 번째 요소인지 알 수 있기 때문이다. 즉, 괄호 안에 수식을 먼저 계산한다.
int tmp = score[i+1];
* 유효한 범위를 벗어난 index는 컴파일러에서 걸러주지 못한다.
왜냐하면 배열의 index로 변수를 많이 사용하는데, 변수의 값은 실행 시에 대입되므로 컴파일러는 이 값의 범위를 확인할 수 없다.
배열의 길이
배열이름.length - 배열의 길이(int형 상수)
배열의 길이는 당연히 양의 정수(0 포함), 최대값은 int타입의 최대값(약 20억)
int[] arr = new int[5]; // 길이가 5인 int 배열
int tmp = arr.length // arr.length의 값은 5이고, tmp에 5가 저장도니다.
길이가 0인 배열도 생성이 가능하다.
int[] arr = new int[0];
배열은 한번 생성하면 실행하는 동안 그 길이를 바꿀 수 없다. 그래서 이미 생성된 배열의 길이(배열이름. length)는 상수다.
변경에 불리한 코드
int[] name = new int[5];
for(int i = 0;i < 5;i++)
System.out.println(i);
변경에 유리한 코드
int[] name = new int[5];
for(int i = 0;i < name.length;i++)
System.out.println(i);
배열의 길이를 변경하기
배열을 한번 선언하면 배열의 길이를 변경할 수 없기에
더 큰 배열의 길이를 생성하고 이를 복사한다.
1. 더 큰 배열을 새로 생성한다.
2. 기존 배열의 내용을 새로운 배열에 복사한다.
배열의 초기화
배열의 각 요소에 처음으로 값을 저장하는 것
배열은 기본적으로 자동초기화 한다(해당 타입의 default 값으로 자동초기화됨)
1. 배열을 선언하고 나중에 값을 할당하는 방법
int[] numbers = new int[5];
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;
2. 배열을 선언하면서 값을 할당하는 방법
int[] numbers = {10, 20, 30, 40, 50}; // new int[] 생략가능
int[] numbers = new int[]{10, 20, 30, 40, 50};
배열을 값을 선언한 후 위와 같이 초기화하는 경우 { } 대괄호만 사용하면 에러 발생.
그래서 new int []{ } 대괄호를 사용해야한다. 즉, 생성사 변수를 붙여주어야 한다.
int[] age;
age = { 1,2,3,4 }; // 에러 발생
age = new int[]{ 1,2,3,4} // OK
3. 매서드의 매개변수에서도 new int[ ]를 생략할 수 없다.
int multiply(int[] arr) // 라는 매서드가 있을때
int result = multiply(new int[]{1,2,3}); // OK
int result = multiply({1,2,3}); // ERROR, 매개변수에 new int[] 생략불가
4. 길이가 0인 배열 생성가능함
int[] abc = new int[0]; // 배열의 길이 : 0
int[] sss = {} // 배열의 길이 : 0
int[] aa = new int[]{} // 배열의 길이 : 0
5. 반복문 활용한 초기화
int[] numbers = new int[5];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = (i + 1) * 10;
}
배열의 출력
int[] arr = { 1, 2, 3, 4, 5};
System.out.println(arr); // [I@12312 라고 arr배열의 참조변수의 주소값이 나온다.
이처럼 배열을 바로 출력하면 해당 배열의 참조변수 주소값을 보여준다.
그러나 예외가 있다.
문자의 배열인 경우 변수이름만 출력해도 배열의 요소들을 전부 출력해준다.
char[] chArr = { '1', 'A' , 'B'};
System.out.println(chArr); // 1AB
그래서 배열의 요소들을 출력하기 위해서는 2가지 방법이 있다.
1. 반복문 사용
for(int i = 0;i < arr.length;i++){
System.out.println(arr[i]);
}
2. Arrays.toString() 매서드 사용
배열의 내용을 문자열로 변환해서 출력한다.
System.out.println(Arrays.toString(arr)); // [ 1,2,3,4,5 ]
String 배열의 선언과 생성
배열 선언하면 자동초기화 되어 문자열의 기본값이 null이 각 배열의 요소에 들어간다.
String[] name = new String[3]; // 3개의 문자열을 담을 수 있는 배열을 생성함
name[0] = "kim";
name[1] = "lng";
name[2] = "efe";
또는
String[] name = new String[]{"kim", "lng", "efe"};
String[] name = {"kim", "lng", "efe"};
참조형 배열의 경우 배열에저장되는 것은 객체의 주소이다.
* String클래스는 char 배열에 기능(매서드)을 추가한 것이다.
char배열과 String클래스의 한가지 중요한 차이는 String객체는 읽을 수만 있고 변경할 수 없다.
String str = "AAa";
str = str + 123124; 새로운 문자열("AAa123124")이 str에 저장됨
System.out.println(str); // AAa123124
위 문장에서 문자열 str의 내용이 변경되는 것 같지만, 문자열은 변경할 수 없으므로 새로운 내용의 문자열이 생성된다.
- 변경 가능한 문자열을 다루려면, StringBuffer클래스를 사용하면 된다.
substring
문자열의 일부를 뽑아낸다. 단, 범위의 끝은 포함되지 않는다.
String str = "012345"
str = str.substring(0,4)
System.out.println(str); // 0123(맨 마지막 4번째는 빠진다)
비교
기본형 변수의 값을 비교하는 경우 '==' 연산자를 사용한다.
문자열의 내용을 비교할 때는 equals()를 사용한다(대소문자 구분함)
대소문자를 구분하지 않으려면 equalsIgnoreCase()를 사용함.
char배열과 String클래스의 변환
new String() 매개변수안에 char[ ]배열을 넣으면 문자열로 변환됨
* char [ ] --> String 변환
char[] asdf = new char[]{ 'a', 'b', 'c'};
String aa = new String(asdf);
* String --> char[ ] 변환
String aa = new String(asdf);
char[] df = aa.toCharArray();
2차원 배열
테이블 형태의 데이터를 저장하기 위한 배열
선언 방법 | 선언 예 |
타입[ ][ ] 변수이름 | int[ ][ ] name |
타입 변수이름[ ][ ] | int name[ ][ ] |
타입 [ ]변수이름[ ] | int[ ] name[ ] |
int[][] score = new int[4][3]; // 4행 3열
초기화하려면
score[0][0] = 100; // 1행 1열에 100 저장
System.out.println(score[0][0])// 1행 1열 출력
2차원 배열의 초기화도 1차원 배열의 초기화와 동일한 패턴을 진행된다.
1. 2차원 배열을 미리 선언하고 값을 할당하는 방법
int[][] matrix = new int[3][3];
matrix[0][0] = 1;
matrix[0][1] = 2;
matrix[0][2] = 3;
matrix[1][0] = 4;
matrix[1][1] = 5;
matrix[1][2] = 6;
matrix[2][0] = 7;
matrix[2][1] = 8;
matrix[2][2] = 9;
2. 2차원 배열을 선언하면서 값을 할당하는 방법
new int[][] 생략가능
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int[][] matrix = new int[][]{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
3. 중첩된 for 루프를 사용하여 2차원 배열을 초기화하는 방법
int[][] matrix = new int[3][3];
int value = 1;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = value;
value++;
}
}
가변 배열
2차원 이상의 다차원 배열을 생성할 때 전체 배열 차수 중 마지막 차수의 길이를 지정하지 않고, 추후에 다른 길이 배열을 생성함으로써 고정된 형태가 아닌 보다 유동적 가변 배열 구성함
int[][] name = new int[4][ ]; 첫행이 4행이고 열은 자유로움 /
name[0] = new int[3];
name[1] = new int[3];
name[2] = new int[3];
name[3] = new int[3];
4행 3열인 2차원 배열임
int[][] name = new int[4][ ]; 첫행이 4행이고 열은 자유로움 /
name[0] = new int[3];
name[1] = new int[5];
name[2] = new int[1];
name[3] = new int[3];
다양하게 배열 길이를 제한할 수 있음
Arrays로 배열 다루기
열의 비교와 출력 - equals(), toString()
* 배열의 요소 출력하기
- 1차원 배열의 요소 출력: Arrays.toString()
- 2차원 배열의 요소 출력: Arrays.deepToString()
int[] arr = {0,1,2,3,4};
int[][] arr2D= {{1,2},{3,4}};
배열의 요소 출력(Arrays.toString() 1차원 배열, Arrays.deepToString() 2차원 배열)
System.out.println(Arrays.toString(arr)) : 1차원 배열 출력
System.out.println(Arrays.deepToString(arr2D)) : 2차원 배열 출력
* 배열의 요소의 값이 같은지 비교(equal)
String[][] str2D = new String[][]{{"aa","bb"},{"cc","dd"}};
String[][] str2D2 = new String[][]{{"aa","bb"},{"cc","dd"}};
1차원 배열을 비교할때는 Arrays.eqauls()를 사용한다.
2차원 배열을 비교할때는 Arrays.deepEquals()를 사용한다.
System.out.println(Arrays.equals(str2D,str2D2)); // false 1차원 배열에 적용되는 메소드
System.out.println(Arrays.deepEquals(str2D,str2D2)) //true 2차원 배열에 적용되는 매소드
* 배열의 복사 1 - copyOf(), copyOfRange()
int[] arr = {0,1,2,3,4};
int[] arr2 = Arrays.copyOf(arr, arr.length) // 이때 2번째 매개변수인 arr.length는 복사할 배열의 요소의 갯수다 0,1,2,3,4
int[] arr3 = Arrays.copyOf(arr, 2) // arr3= [0,1]
int[] arr4 = Arrays.copyOf(arr, 4) // arr3= [0,1,2,3]
int[] arr5 = Arrays.copyOf(arr, 9) // arr3= [0,1,2,3,0,0,0,0,0] // 범위를 넘어선 값이면 0으로 저장(자동초기화)
int[] arr6 = Arrays.copyOf(arr,2,4)// arr배열의 2번째 인덱스부터 4번째 인덱스 범위보다 작은 값. 출력: 2,3
int[] arr7 = Arrays.copyOf(arr,0,8)// arr배열의 0번째 인덱스부터 8번째 인덱스 범위까지 출력, 없는 값은 0으로 초기화,
출력: arr7 = {0,1,2,3,4,5,6}
* 배열의 복사 2 - System.arraycopy()
배열의 복사는 for문보다 System.arraycopy()를 사용하는 것이 효율적이다.
System.arraycopy(num,0, new Num, 0, num.length);
num[0]에서 newNum[0]으로 num.length개의 데이터를 복사
배열의 정렬 - sort()
int[] arr = {3,2,0,1,4};
Arrays.sort(arr); 오름차순으로 정렬
System.out.println(Arrays.toString(arr)); [0,1,2,3,4]
'java' 카테고리의 다른 글
collection framework (0) | 2023.08.31 |
---|---|
collection framework : LinkedList (0) | 2023.08.29 |
[java] 조건문, 반복문 (0) | 2023.08.10 |
[정규표현식과 Pattern] (0) | 2023.03.14 |
[java] 연산자 (0) | 2023.03.11 |
댓글