본문 바로가기
언어/JAVA

[참조 타입] 배열(Array)

by 코딩맛집 2023. 1. 24.

5.6 배열 타입

변수는 하나의 값만 저장할 수 있다. 따라서 저장해야 할 값의 수가 많아지면 그 만큼 많은 변수가 필요하다. 이를 해결하기 위해 배열을 사용한다.

 

배열이란?

연속된 공간에 값을 나열시키고, 각 값에 인덱스를 부여해 놓은 자료구조이다. 

 

특징

배열은 같은 타입의 값만 관리한다.

배열의 길이는 늘리거나 줄일 수 없다.

 

배열 변수 선언은 관례적으로 첫 번째 방법을 주로 사용한다.

타입[] 변수;
타입 변수[];

배열 변수는 참조 변수이다. 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 주소를 저장한다. 참조할 배열이 없다면 배열 변수도 null로 초기화할 수 있다.

 

값 목록으로 배열 생성

타입[] 변수 = {값0, 값1};

중괄호 {}는 나열된 값들을 항목으로 가지는 배열을 힙에 생성하고, 번지를 리턴한다. 

 

※ 주의

배열 변수를 미리 선언한 후에는 값 목록을 변수에 대입할 수 없다.

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

배열 변수를 선언한 시점과 값 목록이 대입되는 시점이 다르다면 다음과 같이 new 타입[]을 중괄호 앞에 붙여주면 된다. 타입은 배열 변수를 선언할 때 사용한 타입과 동일하게 주면 된다.

변수 = new 타입[] {값0, 값1};

매개변수가 이미 선언되어 있고, 호출 시 값 목록을 제공하므로 다음과 같이 호출한다.

//메소드 선언
void printItem(int[] scores){ }

//올바른 메소드 호출
printItem(new int[] {95, 85, 95});

new 연산자로 배열 생성

값의 목록은 없지만 향후 값들을 저장할 목적으로 배열을 미리 생성할 수도 있다. 길이는 배열이 저장할 수 있는 항목 수를 말한다. new 연산자는 해당 길이의 배열을 생성하고 배열의 번지를 리턴하기 때문에 배열 변수에 대입할 수 있다. 

타입[] 변수 = new 타입[길이];

배열 길이

배열에 저장할 수 있는 항목 수를 말한다. 읽기만 가능하다.

배열변수.length;

 

5.7 다차원 배열

배열 항목에는 또 다른 배열이 대입될 수 있는데, 이러한 배열을 다차원 배열이라고 부른다. 다음은 2차원과 3차원 배열의 모양을 보여준다. 다차원 배열에서 각 차원의 항목에 접근하는 방법은 다음과 같다.

변수[1차원인덱스][2차원인덱스]...[n차원인덱스]

값 목록으로 다차원 배열 생성

배열 변수 선언 시 타입 뒤에 대괄호 []를 차원의 수만큼 붙이고, 값 목록도 마찬가지로 차원의 수만큼 중괄호를 중첩시킨다. 다음은 두 반의 학생 점수를 저장하는 배열을 생성해보자. 각 반은 1차원 배열이고, 해당 반의 학생 점수는 2차원 배열이라고 볼 수 있다.

int[][] scores = {
	{80, 90, 96}, //1차원 배열의 0 인덱스 : 첫 번째 반 성적
    	{76, 80} //1차원 배열의 1 인덱스 : 두 번째 반 성적
};

반의 개수는 1차원 배열의 길이와 동일하고, 각 반의 학생 수는 2차원 배열의 길이와 동일하다.

 

new 연산자로 다차원 배열 생성

타입[][] 변수 = new 타입[1차원수][2차원수];
타입 초기값
정수 0
실수 0.0
논리 false
참조 null

마지막 차원의 항목의 값은 초기값을 가진다.

 

int[][] scores = new int[2][];
scores[0] = new int[3];
scores[1] = new int[2];

만약 2차원 배열의 길이를 다르게 주려면 위와 같이 1차원 배열의 길이를 2로 해서 배열 객체를 우선 생성하고, 각각의 항목 값으로 길이가 다른 2차열 배열을 대입하면 된다.

 

5.8 객체를 참조하는 배열

String[] languages = new String[3];
languages[0] = "Java";
languages[1] = "Java";
languages[2] = new String("Java");

System.out.println(languages[0] == languages[1]);  //true: 같은 객체를 참조
System.out.println(languages[0] == languages[2]);  //false: 다른 객체를 참조
System.out.println(languages[0].equals(languages[2])); //true: 문자열이 동일

 

5.9 배열 복사

더 많은 저장 공간이 필요하다면 더 큰 길이의 배열을 새로 만들고 이전 배열로부터 항목들을 복사해야 한다. 가장 기본적인 복사 방법은 for문을 이용해서 항목을 하나씩 읽고 새로운 배열에 저장하는 것이다.

 

더 간단한 방법은 System의 arraycopy() 메소드를 이용하면 한 줄만으로도 배열 복사를 할 수 있다.

System.arraycopy(arr1, 0, arr2, 0, arr1.length);
public class ArrayCopyExample {
    public static void main(String[] args){
        String[] oldArray = {"java", "array", "copy"};
        String[] newArray = new String[5];

        System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);

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

//출력
//java, array, copy, null, null

배열의 항목 초기값에서 복사되지 않은 3번과 4번 인덱스 항목은 null을 유지하고 있다. 그리고 항목의 값이 String 객체의 번지이므로 번지 복사가 되어 참조하는 String 객체는 변함이 없다.

 

5.10 배열 항목 반복을 위한 향상된 for문

자바는 배열 및 컬렉션을 좀 더 쉽게 처리할 목적으로 다음과 같은 for 문을 제공한다. 카운터 변수와 증감식을 사용하지 않고, 항목의 개수만큼 반복한 후 자동으로 for 문을 빠져나간다. 1배열에서 가져올 항목이 있을 경우 2변수에 항목을 저장하고, 3실행문을 실행한다.

public class AdvancedForExample {
    public static void main(String[] args){
        int[] scores = {95, 71, 84, 93, 87};
        int sum = 0;
        for(int score: scores){
            sum += score;
        }
        System.out.println("점수 총합 = " + sum);
        double avg = (double) sum/scores.length;
        System.out.println("점수 평균 = " + avg);
    }
}

 

5.11 main() 메소드의 String[ ] 매개변수 용도

String[ ] args 매개변수가 왜 필요한가?

윈도우의 명령 프롬프트나 맥OS의 터미널에서 프로그램을 실행할 때는 요구하는 값이 있을 수 있다. 예를 들어 두 수를 입력받고 덧셈을 수행하는 Sum 프로그램은 실행할 때 다음과 같이 두 수를 요구할 수 있다.

java sum 10 20

공백으로 구분된 10과 20은 문자열로 취급되며 String[] 배열의 항목 값으로 구성된다. 그리고 main() 메소드 호출 시 매개값으로 전달된다.

String x = args[0];
String y = args[1];

//문자열 10과 20을 int타입으로 변환하려면 다음과 같이 강제 타입 변환을 한다.

int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);

 

5.12 열거(Enum) 타입

데이터 중에는 요일이나 계절처럼 한정된 값을 갖는 타입을 열거 타입이라고 한다. 열거 타입을 사용하기 위해서는 먼저 열거 타입 이름으로 소스 파일을 생성하고 한정된 값을 코드로 정의해야 한다. 열거 타입 이름은 첫 문자를 대문자로 하고 다음과 같이 캐멀 스타일로 지어주는 것이 관례이다.

Week.java
MemberGrade.java
public enum Week {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
    }

열거 상수는 열거 타입으로 사용할 수 있는 한정된 값을 말한다. 관례적으로 알파벳으로 정의하며, 모두 대문자로 작성한다. 만약 열거 상수가 여러 단어로 구성될 경우에는 단어와 단어 사이를 언더바로 연결하는 것이 관례이다.

 

열거 타입도 하나의 데이터 타입으므로 변수를 선언하고 사용해야 한다. 열거 타입 Week로 변수를 선언하면 다음과 같다.

Week today;
Week reservationDay;

열거 타입 변수에는 열거 상수를 대입할 수 있는데, '열거타입.열거상수'형태로 작성한다. Week 변수에 열거 상수인 SUNDAY를 대입하는 코드는 다음과 같다. 열거 타입은 참조 타입이므로 NULL도 대입할 수 있다.

Week today = Week.SUNDAY;

열거 변수의 값이 특정 열거 상수인지 비교할 때는 ==와 != 연산자를 사용한다.

 

열거 타입을 사용하는 이유

데이터의 안전성을 위해

 

'언어 > JAVA' 카테고리의 다른 글

[클래스]  (0) 2023.01.26
[객체 지향 프로그래밍]  (0) 2023.01.25
[변수 & 참조 타입] String  (2) 2023.01.23
[참조 타입] 데이터 타입 분류  (0) 2023.01.21
[변수] 타입 변환  (0) 2023.01.17