[Java] 참조 타입 ②

kiteB·2021년 12월 22일
0

Java

목록 보기
6/35
post-thumbnail

오늘은 참조 타입 중, 배열 타입에 대해서 알아보려고 한다.

[ 배열 타입 ]

1. 배열이란?

배열(array)이란 같은 타입의 변수를 연속된 공간에 나열시키고, 각 데이터에 인덱스를 부여해 놓은 자료구조이다.

  • 배열 요소(element): 배열을 구성하는 각각의 값
  • 인덱스(index): 배열에서의 위치를 가리키는 숫자
    • 인덱스는 언제나 0부터 시작하며, 0을 포함한 양의 정수만을 가질 수 있다.

배열은 같은 타입의 많은 양의 데이터를 다룰 때 효율적으로 사용할 수 있도록 하는 자료구조이다.

📌 배열의 특징

  • 같은 타입의 데이터만 저장할 수 있다.
    • 만약 다른 타입의 값을 저장하려고 하면 타입 불일치(Type mismatch) 컴파일 오류가 발생한다.
  • 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없다.

2. 배열의 선언

배열을 선언하는 방법은 다음과 같다.

1. 타입[] 배열이름;
2. 타입 배열이름[];
  • 타입은 배열에 저장될 데이터의 타입을 말한다.
  • 배열 이름은 배열이 선언된 후에 배열에 접근하기 위해 사용한다.

예제

//첫 번째 방법
int[] intArray;
double[] doubleArray;
String[] strArray;

//두 번째 방법
int intArray[];
double doubleArray[];
String strArray[];

3. 배열 생성

배열 항목에 저장될 값의 목록을 가지고 있다면, 다음과 같이 배열 객체를 만들 수 있다.

데이터타입[] 배열이름 = {0,1,2, ... };

중괄호 {}는 주어진 값들을 항목으로 가지는 배열 객체를 힙에 생성하고, 배열 객체의 번지를 리턴한다. 배열 변수는 리턴된 번지를 저장함으로써 참조가 이뤄진다.

📌 값의 목록으로 배열 객체를 생성할 때 주의할 점!

배열 변수를 이미 선언한 후에 다른 실행문에서 중괄호를 사용한 배열 생성은 허용되지 않는다.

타입[] 변수;
변수 = {0,1,2, ... };	//컴파일 에러

이렇게 배열 변수를 미리 선언한 경우, new 연산자를 이용하여 배열을 생성해야 한다. (아래에서 살펴볼 것)


4. new 연산자로 배열 생성

지금 당장은 값의 목록은 가지고 있지 않지만, 앞으로 사용할 예정인 배열을 미리 만들고 싶다면 new 연산자로 배열 객체를 생성할 수 있다.

타입[] 배열이름 = new 타입[배열길이];

new 연산자로 배열을 생성할 경우에는 이미 배열 변수가 선언된 후에도 가능하다.

타입[] 배열이름 = null;
배열이름 = new 타입[배열길이];

예제

int[] intArray = new int[5];

위의 코드는 길이가 5인 int[] 배열을 생성한다.

new 연산자로 배열을 처음 생성할 경우, 배열은 자동적으로 기본값으로 초기화된다.

intArrayint 타입 배열이므로 intArray[0]부터 intArray[4]까지 모두 기본값 0으로 초기화된다.


만약 String 배열을 생성했다면 모두 null값으로 초기화된다.

String[] strArray = new String[5];

📌 타입별 배열 초기화

배열이 생성되고 나서 새로운 값을 저장하려면 대입 연산자를 이용하면 된다.

배열이름[인덱스] =;

예제

int[] scores = new int[3];
scores[0] = 83;
scores[1] = 49;
scores[2] = 72;

5. 배열 길이

배열의 길이란 배열에 저장할 수 잇는 전체 항목 수를 말한다.
코드에서 배열의 길이를 얻으려면 배열 객체의 length 필드를 읽으면 된다.

배열변수.length;

예제

int[] intArray = {10, 20, 30};
int num = intArray.length();	//num 값은 3

length는 읽기 전용 필드이기 때문에, 값을 바꿀 수 없다.


6. 다차원 배열

다차원 배열은 2차원 이상의 배열을 의미하며, 배열 요소로 또 다른 배열을 가지는 배열을 의미한다.

  • 2차원 배열은 배열 요소로 1차원 배열을 가지는 배열
  • 3차원 배열은 배열 요소로 2차원 배열을 가지는 배열
  • 4차원 배열은 배열 요소로 3차원 배열을 가지는 배열

2차원 배열

2차원 배열은 배열의 요소로 1차원 배열을 가지는 배열

2차원 배열을 선언하는 방법은 다음과 같다.

1. 타입[][] 배열이름;
2. 타입 배열이름[][];
3. 타입[] 배열이름[];

2차원 배열을 도식적으로 표현하면 다음과 같다.

int[][] arr = new int[2][3];

배열 arrlength를 구해보면 다음과 같다.

arr.length	//2 (배열 arr의 길이)
arr[0].length	//3 (배열 B의 길이)
arr[1].length	//3 (배열 C의 길이)

7. 객체를 참조하는 배열

기본 타입 배열은 각 항목에 직접 값을 갖고 있지만,
참조 타입 (클래스, 인터페이스) 배열은 각 항목에 객체의 번지를 가지고 있다.

예를 들어, String은 클래스 타입이므로 String[] 배열은 각 항목에 문자열이 아니라, String 객체의 주소를 가지고 있다. 즉, String 객체를 참조하게 된다.

String[] strArray = new String[3];
strArray[0] = "Java";
strArray[1] = "C++";
strArray[2] = "C#";

위의 코드는 배열 strArray를 선언하고 3개의 문자열을 참조하는 배열을 생성한다.
그림으로 표현하면 다음과 같다.

따라서 String[] 배열의 항목도 결국 String 변수와 동일하게 취급되어야 한다.
예를 들어 배열 항목 간에 문자열 비교할 때 == 연산자 대신 equals() 메소드를 사용해야 한다.
==는 객체의 번지 비교이기 때문에 문자열 비교에 사용할 수 없다.


8. 배열 복사

위에서 "한 번 생성된 배열은 길이를 늘리거나 줄일 수 없다."라고 했다.
그렇기 때문에 더 많은 저장 공간이 필요하다면 더 큰 배열을 새로 만들고 이전 배열로부터 항목 값들을 복사해야 한다.

📌 배열 간의 항목 값들을 복사하려면

  • for문을 사용하거나,
  • System.arraycopy() 메소드를 사용하면 된다.

1) for문으로 배열을 복사하는 방법

public class ArrayCopyByForExample {
    public static void main(String[] args) {
        int[] oldIntArray = {1, 2, 3};
        int[] newIntArray = new int[5];

        for (int i = 0; i < oldIntArray.length; i++) {
            newIntArray[i] = oldIntArray[i];
        }
        
        for (int i = 0; i < newIntArray.length; i++) {
            System.out.print(newIntArray[i] + ", ");
        }
    }
}

실행 결과

1, 2, 3, 0, 0,

위 코드는 다음과 같이 배열을 복사시킨다.
복사되지 않은 항목은 int[] 배열의 기본 초기값 0이 그대로 유지된다.

2) System.arraycopy() 메소드를 이용하여 배열을 복사하는 방법

📌 System.arraycopy()를 호출하는 방법
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

  • src: 원본 배열
  • srcPos: 원본 배열에서 복사할 항목의 시작 인덱스
  • dest: 새 배열
  • destPos: 새 배열에서 붙여넣을 시작 인덱스
  • length: 복사할 개수
public class ArrayCopyByExample {
    public static void main(String[] args) {
        String[] oldStrArray = {"java", "array", "copy"};
        String[] newStrArray = new String[5];

        System.arraycopy(oldStrArray, 0, newStrArray, 0, oldStrArray.length);

        for (int i = 0; i < newStrArray.length; i++) {
            System.out.print(newStrArray[i] + ", ");
        }
    }
}

실행 결과

java, array, copy, null, null,

위 코드는 다음과 같이 배열을 복사시킨다.
복사되지 않은 항목은 String[] 배열의 기본 초기값인 null이 그대로 유지된다.

참조 타입 배열일 경우, 배열 복사가 되면 복사되는 값이 객체의 번지이므로 새 배열의 항목은 이전 배열의 항목이 참조하는 객체와 동일하다. 이것을 얕은 복사(shallow copy)라고 한다.
(↔ 깊은 복사(deep copy)는 참조한느 객체도 별도로 생성하는 것을 말한다.)


9. 향상된 for문 ( Enhanced for문 )

JDK 1.5부터 배열과 컬렉션의 모든 요소를 참조하기 위한 Enhanced for문이라는 향상된 for문을 제공한다. 향상된 for문은 반복 실행을 하기 위해 카운터 변수와 증감식을 사용하지 않는다. 배열 및 컬렉션 항목의 개수만큼 반복하고, 자동적으로 for문을 빠져 나간다.

문법은 다음과 같다.

for (타입 변수이름: 배열이나컬렉션이름) {
    배열의 길이만큼 반복적으로 실행하고자 하는 명령문;
}

예제

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

        int[] scores = new int[]{59, 91, 74, 66, 28};

        for (int score : scores) {
            System.out.print(score + " ");
        }
    }
}

실행 결과

59 91 74 66 28
profile
🚧 https://coji.tistory.com/ 🏠

0개의 댓글