티스토리 뷰

한화시스템/백엔드

[BE] JAVA_배열

jjam-mo 2024. 7. 15. 20:59

1. 배열 개요

→ 나중에는 컬렉션을 사용!!

1-1. 배열 정의 및 사용 이유

1-1-1. 배열이란?

💡동일한 자료형(Data Type)의 묶음(→이 묶음을 인지시킨다.)
연속된 메모리(주기억장치, RAM) 공간에 값을 저장하고 사용하기 위한 용도로 사용
배열은 heap 영역에 new 연산자를 통해 할당 
배열의 길이는 최초 선언한 값으로 "고정", 인덱스를 통해 데이터에 접근 가능

1-1-2. 배열을 사용하는 이유

  • 배열을 사용하지 X → 동일한 자료형을 가진 다양한 값들을 각각의 변수에 저장하여 사용
    (모든 변수의 이름을 사용자가 관리)
  • 연관된 데이터를 저장하기 위한 변수의 선언을 줄여주며, 반복문 등을 이용하여 계산과 같은 과정을 쉽게 처리
package com.ohgiraffers.section01.array;

import java.util.Arrays;

public class Application1 {
    public static void main(String[] args) {

        /* 수업목표. 배열에 대해 이해하고 배열의 사용 목적을 이해할 수 있다. */
        int num1 = 10;
        int num2 = 20;
        int num3 = 30;
        int num4 = 40;
        int num5 = 50;

        int sum = 0;

        sum += num1;
        sum += num2;
        sum += num3;
        sum += num4;
        sum += num5;

        System.out.println("sum = " + sum);

        int[] arr = new int[5];     // 초기상태 : [0][0][0][0][0]
        System.out.println(Arrays.toString(arr));
//        arr[0] = 10;
//        arr[1] = 20;
//        arr[2] = 30;
//        arr[3] = 40;
//        arr[4] = 50;

        /* 설명. 반복문을 활용한 배열 초기화 */
        for (int i = 0; i < 5; i++) {
            arr[i] = (i +1) *10;
        }

        /* 설명. 반복문을 활용해 초기화 된 값 확인 */
        for (int i = 0; i < 5; i++) {
            System.out.println(arr[i]);
        }

        /* 설명. 앞서 확인한 값들을 각각 sum에 누적 */
        for (int i = 0; i < 5; i++) {
            sum += arr[i];
        }

        System.out.println("sum = " + sum);


        /* 설명. 1차원 배열을 쉽게 확인하는 방법 */
        System.out.println(Arrays.toString(arr));   // 배열 안에 있는 값을 출력.

    }
}

// 실행 결과
sum = 150

[0, 0, 0, 0, 0]

10
20
30
40
50

sum = 300

[10, 20, 30, 40, 50]

2. 배열

2-1. 1차원 배열 개요

2-1-1. 1차원 배열 선언

  • 배열을 선언할 때 방법
    1. 참조 변수만 먼저 선언하여 크기 및 값을 이후에 초기화
    2. 최초 선언 시 배열의 크기 및 값을 할당

int[] arr = new int[5] 설명

💡 int[] arr = new int[5] 설명
- int[] 는 참조 자료형!! 참조자료형은 4 byte
- new 는 heap 영역으로!!
- heap 영역은 기본값으로 채워진다. heap은 비어있지 않다.
- Stack에는 주소가 저장된다. heap 영역 어딘가에 있어!!
package com.ohgiraffers.section01.array;

public class Application2 {
    public static void main(String[] args) {

        /* 수업목표. 배열의 사용 방법을 익혀 배열을 사용할 수 있다. */
        /* 필기.
          * 배열의 사용 방법
          * 1. 배열의 선언
          * 2. 배열의 크기 할당
          * 3. 배열의 인덱스 공간에 값 대입
          */

        int[] iArr;
//        char cArr[];                // 대괄호가 뒤에 붙어도 돌아가지만 권장되진 X

//        iArr = new int[];           // 배열은 반드시 크기를 할당해 주어야 한다.
        iArr = new int[10];         // 인스턴스화

        char[] cArr = new char[5];  // 선언과 크기 할당 한번에 가능

        /* 설명. 참조자료형 변수 출력 결과 = toString()의 결과 -> 자료형@16진수 주소값 */
        /* 필기. 기본 자료형이 아닌 것을 출력하면 .toString이 붙은 것을 출력하는 것이다. */
        System.out.println("iArr = " + iArr.toString());    // 실제로 .toString이 붙은 것!
        System.out.println("cArr = " + cArr);

        System.out.println("iArr의 10진수 주소: " + iArr.hashCode());
        System.out.println("cArr의 10진수 주소: " + cArr.hashCode());

        cArr = null;
        System.out.println("null을 참조할 시: " + cArr.hashCode());  // .앞에 null이 있으면 볼 수 없다.

        // NullPointerException : 무엇도 가르킬 것이 없다.
        // 가르키는 것이 없으면 heap 에서 낙동강 오리알 신세인 것이 GC(가비지 콜렉터)가 old 영역으로 옮긴다.
        // GC(가비지 콜렉터) -> 면접 많이 나온다!
    }
}

// 실행 결과
// iArr = [I@7344699f
// cArr = [C@7e9e5f8a

// iArr의 10진수 주소: 1933863327
// cArr의 10진수 주소: 2124308362
package com.ohgiraffers.section01.array;

import java.util.Arrays;

public class Application3 {
    public static void main(String[] args) {

        /* 수업목표. 배열에 초기화 되는 자료형별 기본값을 이해할 수 있다. */
        /* 필기.
          * 값의 형태별 기본값
          * 정수: 0
          * 실수: 0.0
          * 논리: false
          * 문자: \u0000
          * 참조: null
          *  */

        int[] iArr = new int[5];
        System.out.println(Arrays.toString(iArr));
        boolean[] bArr = new boolean[6];
        System.out.println(Arrays.toString(bArr));

        /* 설명. 크기 할당 및 초기화를 한번에 하고 싶을 때 */
        int[] iArr2 = {10, 11, 12, 13, 14};             // 안될때가 있다. 이해 안됨!
        int[] iArr3 = new int[]{10, 11, 12, 13, 14};    // 이건 무조건 된다.

        /* 설명. new int[]을 빼고 배열 생성이 안되는 경우 */
//        test({10, 11, 12, 13, 14});           // 오류 발생!!!
//        test(new int[]{10, 11, 12, 13, 14});

        /* 설명. 배열의 각 요소를 확인하는 세 가지 방법 */
        String[] sArr = {"apple", "banana", "grape", "orange"};

        /* 설명. 1. 단순 for문 사용 */
        for (int i = 0; i < sArr.length; i++) {         // .length는 배열의 길이(크기)
            System.out.println(sArr[i]);
        }

        /* 설명. 2. Arrays.toString() 사용 */
        System.out.println(Arrays.toString(sArr));

        /* 설명. 3. for-each문 사용(향상된 for문) */         // 처음부터 끝까지 돌릴 때 사용!
        for (String str: sArr) {     // 왼쪽 : 요소 하나씩 담을 수 있는 변수 / 오른쪽 : 반복할 배열
            System.out.println(str);
        }
    }

    public static void test(int[] arr) { // 배열을 받는 것이 아니라 배열의 주소값을 받는다. 반환값이 참조자료형일 때...

    }
}

/* 실행 결과
[0, 0, 0, 0, 0]
[false, false, false, false, false, false]

apple
banana
grape
orange

[apple, banana, grape, orange]

apple
banana
grape
orange
*/
package com.ohgiraffers.section01.array;

import java.util.Arrays;
import java.util.Scanner;

public class Application4 {
    public static void main(String[] args) {

        /* 수업목표. 배열을 사용하는 예시를 이해하고 적용할 수 있다. */ // 배열 사용? 반복문 쓰겠구나!!
        /* 설명. 5명의 자바 점수를 입력 받아서 합계와 평균을 실수(double)로 구하는 예제 작성 */
        int[] score = new int[5];

        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < score.length; i++) {
            System.out.print((i + 1) + "번째 학생의 자바 점수를 입력해 주세요: ");
            score[i] = sc.nextInt();
        }
        System.out.println("현재까지 입력된 값: " + Arrays.toString(score));    // 중간중간 실행하면서 확인하자(검산)

        /* 설명. 합계(sum) 구하기 */
        int sum = 0;
        for (int perScore: score) {
            sum += perScore;
        }

        System.out.println("합계: " + sum);

        /* 설명. 평균(avg) 구하기 */
        double avg = sum / score.length;
        System.out.println("평균: " + avg);
    }
}
package com.ohgiraffers.section01.array;

public class Application5 {
    public static void main(String[] args) {

        /* 수업목표. 배열을 사용하는 예시를 통해 카드 게임을 작성해 보자. */
        String[] shape = {"SPADE", "CLOVER", "HEART", "DIAMOND"};
        String[] cardNumber = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "JACK", "QUEEN", "KING", "ACE"};

        int randomShapeIndex = (int) (Math.random() * shape.length);            // 0 ~ 3
        int randomCardNumberIndex = (int) (Math.random() * cardNumber.length);  // 0 ~ 12

        System.out.println("당신이 뽑은 카드는 " + shape[randomShapeIndex] + " " + cardNumber[randomCardNumberIndex] + "카드 입니다.");

    }
}

 

 

2-2. 다차원 배열 개요

2-2-1. 2차원 배열 선언

  • 일부 인덱스는 또 다른 배열의 주소를 보관하는 배열 역할
    즉, 2차원 배열은 1차원 배열 여러 개를 하나로 묶어서 관리하는 배열
  • 1차원 배열을 관리하는 또 다른 1차원 배열!

Int[][] iArr = new int[3][4] 설명
heap의 열 부분 오타!
앞에 대괄호 안에 있는 숫자는 행, 뒤에 있는 대괄호 안에 있는 숫자는 열이라고 여겨도 무관!!

package com.ohgiraffers.section02.dimensional;

import java.util.Arrays;

public class Application1 {
    public static void main(String[] args) {

        /* 수업목표. 다차원 배열의 구조를 이해하고 사용할 수 있다. */
        /* 필기.
          * 다차원 배열
          *  다차원 배열은 2차원 이상의 배열을 의미한다.
          *  (일반적으로는 사람의 인지 범위에 맞게 최대 3차원 정도를 고려한다.
         * */

        int[][] iArr1;
        int[] iArr2[];      // 추천 X
        int iArr3[][];      // 추천 X

        iArr1 = new int[3][2];          // 정변 배열을 위한 선언(관리하는 1차원 배열의 길이가 동일)
        iArr2 = new int[3][];           // 가변 배열을 위한 선언(관리하는 1차원 배열의 길이가 다를 시)
//        iArr3 = new int[][];            // 컴파일 에러 발생

        int num = 0;
        for (int i = 0; i < iArr1.length; i++) {                // 1차원 배열을 고르는 for문
            System.out.println("iArr1[i] = " + iArr1[i]);       // 관리하는 1차원 배열 주소값
            for (int j = 0; j < iArr1[i].length; j++) {         // 선택된 1차원 배열을 다루는 for문
                iArr1[i][j] = num++;
            }
            System.out.println(Arrays.toString(iArr1[i]));
        }

        /* 설명. Arrays.toString()은 1차원 배열만 확인 가능하다. */
        System.out.println("2차원 배열도 한번에 확인 될까? " + Arrays.toString(iArr1));

        /* 설명. 가변배열에 다양한 길이의 1차원 배열을 적용해 보자. */
        iArr2[0] = new int[]{1, 2, 3};
        iArr2[1] = new int[]{1, 2, 3, 4};
        iArr2[2] = new int[]{3, 3};

        for (int i = 0; i < iArr2.length; i++) {
            System.out.println(Arrays.toString(iArr2[i]));
        }
    }
}

// 실행 결과
iArr1[i] = [I@6b95977
[0, 1]
iArr1[i] = [I@7e9e5f8a
[2, 3]
iArr1[i] = [I@8bcc55f
[4, 5]

2차원 배열도 한번에 확인 될까? [[I@6b95977, [I@7e9e5f8a, [I@8bcc55f]

[1, 2, 3]
[1, 2, 3, 4]
[3, 3]

 

3. 배열의 복사

3-1. 배열의 복사 개요

3-1-1. 배열의 복사란?

💡 자바에서는 배열은 목적에 따라 복사를 해야 할 경우가 있다.

3-1-2. 복사의 종류

💡 배열의 2가지 복사
1. 얕은 복사(shallow copy) : stack 의 주소값만 복사, 원본을 공유할 목적
2. 깊은 복사(deep copy) : heap의 배열에 저장된 값을 복사, 원본과 사본을 분리하여 관리 할 목적 → 원본에 영향 가지 않는다.

3-2. 얕은 복사 개요

3-2-1. 얕은 복사란?

얕은 복사는 레퍼런스 변수 안에 담긴 주소값을 새로운 레퍼런스 변수에 복사하는 것

package com.ohgiraffers.section03.copy;

import java.util.Arrays;

public class Application1 {
    public static void main(String[] args) {

        /* 수업목표. 배열의 복사 개념 중 얕은 복사에 대해 이해할 수 있다. */
        /* 필기.
        *   배열의 복사에는 크게 두 가지 개념이 있다.
        *   1. 얕은 복사(shallow copy): stack의 주소 값만 복사
        *   2. 깊은 복사(deep copy): heap의 배열에 저장된 값을 복사
        * */

        int[] originArr = {1, 2, 3};
        int[] copyArr = originArr;      // 참조 주소 값 복사(얕은 복사) / 활용하는 걸 이해하자!!

        System.out.println(Arrays.toString(copyArr));

        copyArr[2] = 100;
        System.out.println(Arrays.toString(originArr));

        test(originArr);    // 이렇게 해도 얕은 복사가 일어난다.
                            // int[] arr = originArr;
    }

    public static void test(int[] arr) {

    }
}

// 실행 결과
[1, 2, 3]
[1, 2, 100]

3-3. 깊은 복사 개요

3-3-1. 깊은 복사란?

새롭게 할당한 힙 영역에 기존 배열의 값을 복사한 후 새롭게 생셩된 배열의 주소값을 넘겨주는 것

package com.ohgiraffers.section03.copy;

import java.util.Arrays;

public class Application2 {
    public static void main(String[] args) {

        /* 수업목표. 깊은 복사에 대해 이해할 수 있다. */
        /* 필기.
        *   깊은 복사를 하는 방법은 4가지가 있다.
        *   1. for문을 이용한 동일한 인덱스 값을 일일이 복사
        *   2. Object의 clone()을 이용한 복사(사용 빈도 높음)
        *   3. System의 arraycopy()를 이용한 복사
        *   4. Arrays의 copyOf()를 이용한 복사
        * */

        int[] originArr = new int[]{1, 2, 3, 4};
        print(originArr, "원본");

        /* 목차. 1. for문 활용 */
        int[] copyArr1 = new int[originArr.length];
        for (int i = 0; i < copyArr1.length; i++) {
            copyArr1[i] = originArr[i];
        }
        print(copyArr1, "for문을 활용한 사본");    // print 어떻게 사용?? print 클래스!!

        /* 목차. 2. clone() 활용 */
        int[] copyArr2 = originArr.clone();
        print(copyArr2, "clone()을 활용한 사본");

        /* 목차. 3. arraycopy()를 이용한 복사 */
        int[] copyArr3 = new int[originArr.length + 3];        // 원본보다 3 크기가 더 큰 배열 할당
        System.arraycopy(originArr, 0, copyArr3, 3, 3);
        print(copyArr3, "arraycopy()를 활용한 사본");

        /* 목차. 4. copyOf()를 이용한 복사(원본의 처음부터만 가능) */
        int[] copyArr4 = Arrays.copyOf(originArr, 2);
        print(copyArr4, "copyOf()를 활용한 사본");
    }

    public static void print(int[] arr, String desc) {  // 출력 편하게 하기 위해
        System.out.println("=======" + desc + "=======");

        System.out.println("넘어온 배열의 hashCode: " + arr.hashCode());

        System.out.println(Arrays.toString(arr));
    }
}

// 실행 결과
=======원본=======
넘어온 배열의 hashCode: 205029188
[1, 2, 3, 4]
=======for문을 활용한 사본=======
넘어온 배열의 hashCode: 2018699554
[1, 2, 3, 4]
=======clone()을 활용한 사본=======
넘어온 배열의 hashCode: 1311053135
[1, 2, 3, 4]
=======arraycopy()를 활용한 사본=======
넘어온 배열의 hashCode: 118352462
[0, 0, 0, 1, 2, 3, 0]
=======copyOf()를 활용한 사본=======
넘어온 배열의 hashCode: 1550089733
[1, 2]

 

'한화시스템 > 백엔드' 카테고리의 다른 글

[BE] JAVA_클래스와 객체_캡슐화  (0) 2024.07.16
[BE] JAVA_클래스와 객체  (0) 2024.07.15
[BE] JAVA_분기문  (0) 2024.07.13
[BE] JAVA_반복문  (0) 2024.07.13
[BE] JAVA_조건문  (0) 2024.07.13
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함