Java

[Java] 배열 타입

콩스프 2022. 10. 31. 04:22

배열이란?

  • 변수한 개의 데이터만 저장할 수 있음
    → 저장해야 할 데이터의 수가 많아지면 그만큼 많은 변수가 필요

EX) 학생 30명의 성적을 저장하고 평균 값 구하기

① 30명의 성적을 저장하기 위해 변수 30개를 선언해야 함

int score1 = 85;
int score2 = 90;
int score3 = 87;
...
int score30 = 75;

② 평점을 구하기 위해 변수들을 모두 더해야 함

int sum = score1;
sum += score2;
sum += score3;
...
sum += score30;
int avg = sum/30;

"매우 비효율적이고 지루한 코딩"

만약 전교 학생들에 대한 성적을 처리한다면? 수백 개의 변수 선언을 해야함

 

 

같은 타입의 많은 양의 데이터를 다루는 프로그램에서는 좀 더 효율적인 방법이 필요함  ➡ 배열

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

EX) 배열을 사용하여 학생 30명의 성적을 저장하고 평균 값 구하기

① 학생들의 성적을 score 배열로 생성

  • score 배열의 각 인덱스는 각 항목의 데이터를 읽거나, 저장하는데 사용됨
  • 대괄호 [ ] 에 기입 됨
    EX) score[0] = 83, score[1] = 90, score[2] = 87
score[인덱스]

 

② for문을 사용하여 점수를 더하고 쉽게 평균값을 구할 수 있음

int sum=0;
for(int i=0; i<30; i++) {
	sum += score[i];
}
int avg = sum/30;
  • for문이 30번 반복 실행하면서 i가 0~19까지 변함
  • sum 변수에는 score[0] ~ score[29] 까지 더해짐
  • 마지막으로 얻은 sum을 30으로 나누어 평균 avg를 얻음
  • 학생수가 30명이 아니라 수백 명이 되어도 for문의 i<30만 변경하면 되므로 많은 양의 데이터를 쉽게 처리할 수 있음

 

 

배열의 특징

  • 배열은 같은 타입의 데이터만 저장할 수 있음
    • int 타입 배열은 int 값만 저장 가능하고, String 배열은 문자열만 저장 가능
  • 배열은 선언과 동시에 저장할 수 있는 데이터 타입이 결정
    • 만약 다른 타입의 값을 저장하려고 하면 타입 불일치 (Type mismatch) 컴파일 오류 발생
  • 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없음
    • 3개의 값을 저장하는 배열 생성 → 프로그램 실행 도중 5개의 값을 저장하는 배열로 수정X
                                                                    반대로 2개의 값만 저장하는 배열로 수정X
    • 만약 5개의 값을 저장해야 한다면? → 길이 5의 새로운 배열 생성 후 기존 배열 항목을 새 배열로 복사

 

 

배열 선언

  • 배열을 사용하기 위해서는 우선 배열 변수를 선언해야 함
  • 배열 변수 선언은 두 가지 형태로 작성할 수 있음
타입[] 변수;
타입 변수[];

 

  • 대괄호 [ ]는 배열 변수를 선언하는 기호로 사용됨
  • 타입 뒤에 붙을 수도 있고 변수 뒤에 붙을 수도 있음
  • 타입은 배열에 저장될 데이터의 타입을 말함
int[] intArray;
double[] doubleArray;
String[] strArray;
int intArray[];
double doubleArray[];
String strArray[];

 

  • 배열 변수는 참조 변수에 속함
  • 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조하게 됨
  • 참조할 배열 객체가 없다면 배열 변수는 null 값으로 초기화될 수 있음
  • 배열 변수가 null 값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하게 되면 NullPointerException이 발생
  • 배열 변수는 배열을 생성하고 참조하는 상태에서 값을 저장하거나 읽어야 함
타입[] 변수 = null;

 

 

값 목록으로 배열 생성

  • 배열 항목에 저장될 값의 목록이 있다면, 간단하게 배열 객체를 만들 수 있음

데이터타입[] 변수 = { 값0, 값1, 값2, 값3, ...};

 

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

EX) "홍길동", "김철수", "이영희" 문자열을 갖는 배열

String[] names = {"홍길동", "김철수", "이영희"};
  • "홍길동"은 names[0], "김철수"는 names[1], "이영희"는 names[2]로 읽을 수 있음

 

  • names[1]의 "김철수"를 "김수철"로 바꾸고 싶다면 대입 연산자를 사용하면 됨
naems[1] = "김수철";

 

주의할 점

  • 배열 변수를 이미 선언한 후다른 실행문에서 중괄호를 사용한 배열 생성허용되지 않음
타입[] 변수;
변수 = { 값0, 값1, 값2, 값3, ... } //컴파일 에러

 

  • 배열 변수를 미리 선언한 후, 목록들이 나중에 결정되는 상황이라면 new 연산자를 사용해서 값 목록을 지정
  • new 연산자 바로 뒤에는 배열 변수 선언에서 사용한 "타입[ ]"을 붙여주고 중괄호 { }에는 값들을 나열
변수 = new 타입[] { 값0, 값1, 값2, 값3, ... }

 

값의 리스트로 배열 생성 EX)

String[] names = null
names = new String[] { "홍길동", "김철수", "이영희" };

 

메소드의 매개값

  • 매개 변수로 배열이 선언된 메소드가 있을 경우
  • 값 목록으로 배열을 생성함과 동시에 메소드의 매개값으로 사용하고자 할 때 반드시 new 연산자를 사용해야 함
int add(int[] scores) {
	...
}

int result = add( {95, 85, 90} ); //컴파일 에러
int result = add( new int[] {95, 85, 90} );

 

값의 리스트로 배열 생성 EX2)

package reference;

public class ArrayCreateByValueList {

	public static void main(String[] args) {
		int[] scores;
		scores = new int[] {83, 90, 87};
		int sum1 = 0;
		for(int i=0; i<3; i++) {
			sum1 += scores[i];
		}
		System.out.println("총합 : " + sum1);
		
		int sum2 = add( new int[] {83, 90, 87} ); //리턴된 총 합을 sum2에 저장
		System.out.println("총합 : " + sum2);
		System.out.println();
	}
	
	//총합을 계산해서 리턴하는 메소드
	public static int add(int[] scores) {
		int sum = 0;
		for(int i=0; i<3; i++) {
			sum+=scores[i];
		}
		return sum;
	}

}

실행 결과

 

 

new 연산자로 배열 생성

  • 값의 목록을 가지고 있지 않지만, 향후 값들을 저장할 배열을 미리 만들고 싶다면 new 연산자로 객체를 생성
타입[] 변수 = new 타입[길이];

 

  • 길이는 배열이 저장할 수 있는 값의 수를 말함
  • new 연산자로 배열을 생성할 경우에는 이미 변수가 선언된 후에도 가능
타입[] 변수 = null;
변수 = new 타입[길이];

 

new연산자로 배열 생성 EX)

int[] intArray = new int[5];
  • 길이가 5인 int[ ] 배열을 생성
  • 자바는 intArray[0] ~ intArray[4]까지 값이 저장될 수 있는 공간을 확보하고 배열의 생성 번지를 리턴
  • 리턴된 번지는 intArray 변수에 저장됨
  • 각각의 항목 크기는 int 타입의 크기인 4byte가 됨

 

  • 배열이 생성되고 나서 새로운 값을 저장하려면 대입 연산자를 사용하면 됨
변수[인덱스] = 값;
int[] scores = new int[3];
scores[0] = 83;
scores[1] = 90;
scores[2] = 75;

 

타입별 배열의 초기 값

  • new 연산자로 배열을 처음 생성할 경우, 배열은 자동적으로 기본값으로 초기화
분류 데이터 타입 초기값
기본 타입 (정수) byte[ ]
char[ ]
short[ ]
int[ ]
long[ ]
0
'\u0000'
0
0
0L
기본 타입 (실수) float[ ]
double[ ]
0.0F
0.0
기본 타입 (논리) boolean[ ] false
참조 타입 클래스[ ] null
인터페이스[ ] null

배열 초기값 EX1)

int[] scores = new int[30];
  • scores 배열은 int 타입 배열이므로 scores[0] ~ scores[29] 까지 모두 기본 값 0으로 초기화

 

배열 초기값 EX2)

String[] names = new String[30];
  • names 배열은 String 배열 이므로 names[0] ~ names[29] 까지 모두 null 값으로 초기화

 

 

배열 길이

  • 배열의 길이 : 배열에 저장할 수 있는 전체 항목 수
  • 코드에서 배열의 길이를 얻으려면 배열 객체의 length *필드를 읽으면 됨
    *필드 : 객체 내부의 데이터
  • 배열의 length 필드를 읽기 위해서는 배열 변수에 도트(.) 연산자를 붙이고 length 를 적으면 됨
배열변수.length;
  • 배열의 인덱스 범위 : 0 ~ (길이-1)
  • 인덱스를 초과해서 사용하면 ArrayIndexOutOfBoundsException이 발생
  • length 필드읽기 전용 필드이기 때문에 값을 바꿀 수 없음
intArray.length = 10; //잘못된 코드

 

length로 배열의 길이 얻기 EX)

int[] intArray = {10,20,30};
int num = intArray.length;
  • 배열 intArray가 3개의 값을 가지고 있기 때문에 변수 num에는 3이 저장됨

 

length 필드 사용 EX)

int[] scores={83,90,87};

int sum=0;
for(int i=0; i<scores.length; i++) {
	sum+= scores[i];
}
  • 배열의 length 필드 for문을 사용해서 배열 전체를 루핑할 때 매우 유용하게 사용할 수 있음
  • for문의 조건식에서 < 연산자를 사용하는 이유는 배열의 마지막 인덱스는 배열 길이보다 1이 적기 때문