자바의 정석 chap 5 배열

개발자 macan·2022년 8월 5일
0

개발 - 공부

목록 보기
28/28

Chapter 5. 배열

5.1 배열(array)

  • 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것

  • 위는 배열을 사용하지 않을 시의 저장된 변수 5개
  • 배열은 각 저장공간이 연속적으로 배치되어있다.

5.2 선언, 생성, 초기화

- 선언 : 배열의 주소가 저장되는 장소, 즉 배열을 다루는데 필요한 변수

  • 원하는 타입의 변수를 선언하고 변수 또는 타입에 배열을 의미하는 대괄호[]를 붙인다.
  • 선언은 참조변수를 위한 공간이 만들어 지는 것.

- 생성 : 배열의 값을 저장할 공간이 생성

  • 배열을 생성하기 위해서는 연산자 'new'와 함께 배열의 타입과 길이를 지정해야한다.
public static void main(String[] args) {
    int[] arr; // 배열 선언
    arr = new int[5]; // 5개의 int 값을 저장할 수 있는 공간 생성
}
  • 선언과 동시에 공간을 생성할 수도 있다.
public static void main(String[] args) {
    int[] arr = new int[5];// 선언과 동시에 생성
}

- 배열의 길이와 인덱스

- 인덱스
  • 생성된 배열의 저장공간을 '배열의 요소'라 한다.
  • 인덱스는 배열의 요소마다 붙여진 일련번호.
  • "인덱스의 범위는 0부터 '배열길이-1'까지"
  • 배열을 저장하고 읽어올 때 변수와 달리 변수 이름대신 '배열이름[인덱스]'를 사용한다.

ex)

score[3] = 100; / 배열 score의 4번째 요소에 100을 저장
int value = score[3]; / 배열 score의 4번째 요소의 값을 읽어 value에 저장

- index로 상수대신 변수나 수식도 사용할 수 있다!

for (int i=0; i < 5; i++) {
	score[i] = i * 10;
}
  • for문의 제어변수 i는 배열의 index로 쓰기에 좋아서 배열을 다룰 때 for문은 필수!
  • 괄호안에 수식이 포함된 경우, 수식이 먼저 계산된다.
    ex)
int tmp = score[i+1];

유효한 범위의 값을 벗어난 값을 index로 사용하면 안된다!
-> 그 결과는 ERROR (ArrayIndexOutOfBoundsException)

- 배열의 길이
  • 배열의 요소의 개수, 값을 저장할 수 있는 공간의 개수
  • 최대값은 Int타입의 최대값 약 20억
  • 길이가 0인 배열도 생성이 가능하다.
int[] score = new int[5]; 

for (int i =0; i < score.length; i++) {
	System.out.println(score[i]);
}
  • 길이의 출력 : '배열이름.length' <- 변하지 않는 상수!
  • '배열이름.length'를 사용하는 것이 코드의 관리가 쉽고 에러 확률이 줄어든다.
  • 배열의 길이를 변경하는 법
    (1) 더 큰 배열을 새로 생성
    (2) 기존 배열의 내용을 새로운 배열에 복사

- 초기화 :

  • 배열은 생성과 동시에 자동으로 맞는 타입의 기본값으로 초기화되어 굳이 사용전에 초기화 할 필요는 없다.
  • 원하는 값을 저장하려면 각 요소마다 값을 지정해야한다.
public static void main(String[] args) {
    int[] arr = {1,2,3,4,5};// 선언과 동시에 생성
}
  • 배열 출력할때도 for문을 사용한다.
int[] iArr = { 100, 95, 80, 70, 60};
for(int i =0; i < iArr.length; i++) {
	System.out.println(iArr[i]);
}
  • println은 줄바꿈이 있으니 이것이 싫다면 print를 사용한다.
int[] iArr = { 100, 95, 80, 70, 60};
for(int i =0; i < iArr.length; i++) {
	System.out.print(iArr[i]+",");
}
System.out.println();

배열의 복사

  • 배열은 한번 생성시 길이를 변경할 수 없다.
  • 새로 만들기 위해서는 큰 배열을 새로 만들고 이전 배열 내용을 복사해야한다.
  • 방법 두가지
  • 1) for 문을 이용
int[] arr = new int[5];

int[] tmp = new int[arr.length*2];

for(int i =0; i < arr.length; i++)
	tmp[i] = arr[i];
    
arr = tmp;
  • 이 작업은 비용이 많이 들기 때문에 배열의 길이를 넉넉하게 2배정도로 설정하는 것이 좋다.

  • 2) System.arraycopy() 이용

  • 배열의 복사는 for문보다 System.arraycopy()를 사용하는 것이 효율적이다.

for(int i =0; i < num.length; i++) { newNum[i] = num[i]; }
=> System.arraycopy(num, 0, newNum, 0, num.length);
// num[0]에서 newNum[0]으로 num.length개의 데이터를 복사

public static void main(String[] args){
    int[] arr = {1,2,3,4,5};
    int[] arr2 = arr; // 가능할까?
    arr[2] = 100;
    System.out.println(Arrays.toString(arr2));
}
> [1, 2, 100, 4, 5]

arr2도 같은 값을 가진다. 하지만 단순히 주소를 복사한 것이므로 arr, arr2는 같은 메모리 주소를 갖는다.
따라서 arr의 값을 바꾼다면 arr2에서 호출할 때 바뀐 값이 나온다.

- 배열을 다루는 유용한 메서드(Arrays)

배열을 다루기 위해 배열 자체의 메소드와 Arrays 객체의 메소드를 활용해서 사용한다.

  • (1) 배열의 길이
    배열.length
public static void main(String[] args){
    int[] arr = {1,2,3,4,5};
    System.out.println(arr.length);
    >> 5
}
  • (2) 배열의 출력
    Arrays.toString(배열)
public static void main(String[] args){
    int[] arr = {1,2,3,4,5};
    System.out.println(Arrays.toString(arr));
    >> [1,2,3,4,5]
}

Arrays로 배열 다루기(메서드)
// toString, deepToString, equals, deepEquals

public static void main(String[] args) {
		int[] arr = {1,2,3,4,5};
		int[] arr2 = {1,2,3,4,5};
		int[][] arr2D = {{1,2,},{3,4}};
		int[][] arr2D2 = {{1,2,},{3,4}};
		System.out.println("Arrays.toString(arr) : " + Arrays.toString(arr));
		System.out.println("Arrays.equals(arr,arr2) : " + Arrays.equals(arr,arr2));
		System.out.println("arr.equals(arr2) : " + arr.equals(arr2));
		System.out.println("Arrays.deepToString(arr2D) : " + Arrays.deepToString(arr2D));
		System.out.println("Arrays.deepEquals(arr2D, arr2D2) : " + Arrays.deepEquals(arr2D, arr2D2));
	}

Arrays.toString(arr) : [1, 2, 3, 4, 5]
Arrays.equals(arr,arr2) : true
arr.equals(arr2) : false
Arrays.deepToString(arr2D) : [[1, 2], [3, 4]]
Arrays.deepEquals(arr2D, arr2D2) : true
배열의 주소가 아닌 배열의 값을 복사하는 방법

  • (3) 주소 복사 vs copyOf 사용
public static void main(String[] args) {
		int[] arr = {1,2,3,4,5};
		int[] arr2 = arr;
		int[] arr3 = Arrays.copyOf(arr, arr.length);
		System.out.println("arr = " + arr); // 같은 메모리 주소
		System.out.println("arr2 = " + arr2); // arr와 같은 메모리 주소
		System.out.println("arr3 = " + arr3);
		arr[3] = 100;
		System.out.println("arr[3] = " + arr[3]);
		System.out.println("arr2[3] = " + arr2[3]);
		System.out.println("arr3[3] = " + arr3[3]);
	}
> arr = [I@28d93b30
> arr2 = [I@28d93b30
> arr3 = [I@1b6d3586
> arr[3] = 100
> arr2[3] = 100
> arr3[3] = 4

5.3 String class

  • String은 문자열이라고 부르며 기본 자료형과 다른 클래스(객체)다.
  • String은 char배열에 기능(메서드)를 추가한 것

String 메서드

public static void main(String[] args) {
		//String 메소드
		String string = "ABCDE";
		System.out.println("string.charAt(3) = " + string.charAt(3)); // 문자열에서 특정 인덱스 문자 구하기
		System.out.println("string.substring(1,3) = " + string.substring(1,3)); // 문자열에서 특정 문자열을 인덱스 범위로 구하기
		System.out.println("string.equals(\"ABCDE\") = " + string.equals("ABCDE")); // 문자열 비교
		char[] charArr = string.toCharArray(); // 문자열에서 char배열로 바꾸기
		System.out.println("charArr.toString() = " + charArr.toString());
		System.out.println("string.toCharArray().toString() = " + string.toCharArray().toString());
	}

>> string.charAt(3) = D
>> string.substring(1,3) = BC
>> string.equals("ABCDE") = true
>> charArr.toString() = [C@28d93b30
>> string.toCharArray().toString() = [C@1b6d3586
// 정렬
public static void main(String[] args) {
		int[] arr = {3, 2, 5, 4, 1};
		Arrays.sort(arr);
		System.out.println("Arrays.toString(arr) = " + Arrays.toString(arr));
	}

Arrays.toString(arr) = [1, 2, 3, 4, 5]

5.4 다차원 배열

2차원 배열의 선언과 인덱스

  • 1차원 배열에서 괄호[]를 하나 더 넣는다.
    ex)
int[][] score = new int[4][3]; / 4행 3열의 2차원 배열
  • 인덱스 : '배열이름[행index][열index]'
  • 위의 경우 score[0][0] -> score[3][2]까지 12개

2차원 배열의 초기화

  • 2차원 배열도 괄호{}를 사용하여 생성과 초기화가 가능하다.
    ex)
int[][] arr = {
					{1,2,3},
                    {4,5,6}
              };
  • for문을 사용한 초기화
for (int i = 0; i< score.length; i++) {
	for (int j=0; j < score[i].length; j++) {
    	score[i][j] = 10;
    }
}

예제 - 2차원 배열 score의 모든 요소의 합을 구하고 출력

for (int[] tmp : score) {
	for (int i : tmp) {
    	sum += i;
    }
}

가변배열

  • 2차원 이상의 다차원 배열을 생성할 때 전체 배열 차수 중 마지막 차수의 길이를 지정하지 않고, 추후에 각기 다른 배열을 생성함으로써 고정된 형태가 아닌 보다 유동적인 가변 배열을 구성할 수 있다.

다차원 배열의 활용

  • 좌표에 x표하기
  • 빙고
  • 행렬의 곱셈
  • 단어 맞추기
profile
개발자로 첫걸음

0개의 댓글