본문 바로가기
백엔드/Java

[Java] 5. 배열(Array)

by BGwon_C 2023. 7. 31.

배열이란?

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

여기서 중요한 건 '같은 타입'이어야 한다는 것이다. 자바는 서로 다른 타입의 변수들로 된 배열을 만들 수 없다.

또한 하나의 묶음이란 각 저장공간이 연속적으로 배치되어 있다는 것을 의미한다.

 


배열의 선언과 생성

배열을 사용하기 위해선 먼저 배열을 선언하고, 선언한 배열을 사용하기 위한 저장공간을 생성해야 한다.

타입[ ] 변수이름 = new 타입 [길이];
배열의 선언          배열의 생성

(배열 선언시 대괄호를 변수명 옆에 붙여도 되지만, 보통은 타입 옆에 붙인다. 타입 변수이름[ ])

 

여기서 중요한 건 배열의 선언은 단지 앞으로 생성할 배열의 주소값을 참조하는 것에 불과하다는 것이다. 배열을 선언하면 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어질 뿐이고, 배열을 생성해야 비로소 값을 저장할 수 있는 공간이 만들어진다. 

 


배열과 인덱스(Index)

생성된 배열의 각각의 저장공간을 배열의 요소라고 하며, 인덱스는 각 배열의 요소마다 붙여진 일련번호라고 보면 된다.

우리가 배열에 접근할 때, 이 인덱스 번호를 이용해서 각 요소에 접근하는 것이 가능하다. 이때 인덱스 번호에는 상수 대신 변수나 수식도 사용이 가능하다.

참고로 배열의 인덱스는 0번부터 시작하기때문에 배열의 요소의  순서를 셀 때에는 '인덱스 번호 +1'을 해야 한다.

 

int[] score = new int[5];  // 길이가 5인 int배열

score[3] = 100;   // score배열의 4번째 요소에 정수 100을 저장한다.

score[i] = 200;  //  score배열의 i번째 요소에 정수 200을 저장. 주로 for문같은 반복문을 사용하여 배열의 모든 요소에 한 번에 값을 저장할 때 사용한다.

 

배열은 한 번 생성하면 길이를 변경하는 것이 불가능하다. (물론 Arrays 클래스의 copyOf 메서드처럼 객체배열에서 변경 가능한 특정 메서드를 지원하는 경우도 있지만 이건 좀 더 뒤의 이야기이고 일반 배열에선 변경이 안 된다는 것만 알아두면 된다.)

 


배열의 초기화 및 출력

배열은 생성과 동시에 자동적으로 기본값(0)으로 초기화되므로, 원하는 값을 저장하려면 각 요소마다 값을 지정해 줘야한다. 배열의 값을 지정하는 방법은 여러가지가 있다.

 

		// 1. 각 요소에 직접 값을 저장하는 방법
		int[] score = new int[3];
		score[0] = 50;
		score[1] = 60;
		score[2] = 70;
		System.out.println(score);                  // score배열의 주소값 [I@3d012ddd 출력
 		System.out.println(score[0]);               // score배열의 0번째 요소의 값 50 출력
		
		// 2. for문을 이용하여 값을 저장하는 방법
		int[] score1 = new int[3];
		for(int i=0; i<score1.length; i++) {
			score1[i] = i * 10 + 50;
		}
		System.out.println(Arrays.toString(score1)); // score1배열의 값 [50, 60, 70] 출력
		
		// 3. 간단하게 new타입[]을 생략하여 배열의 생성과 초기화를 동시에 하는 방법
		int[] score2 = new int[] {50, 60, 70};
		
		// 단, 배열의 선언과 생성을 따로 하는 경우에는 new int[]를 생략할 수 없다.
		int[] score3;
		//score = {50, 60, 70};          // 에러. new int[] 생략 불가
		score3 = new int[] {50, 60, 70};
		
		char[] chArr = {'a', 'b', 'c'};
		System.out.println(chArr);                    // abc출력

 

또한, 배열을 출력할 때 유의해야 할 점은 그냥 배열변수명을 출력하면 배열의 값이 출력되는 것이 아니라 배열연수의 주소값이 출력된다는 것이다.

이는 배열변수가 단지 저장한 배열의 주소를 가리키는 참조변수를 담는 공간에 불과하기 때문이다. 만일 해당 배열변수가 가리키는 배열 요소의 값을 출력하고 싶다면 배열명[요소번호] 을 사용하면 된다.

 

더 간단하게 배열의 값을 출력하는 방법은 Arrays.toString(배열명) 메서드를 사용하면 된다. 이 메서드는 배열의 모든 요소를 문자열의 형식으로 반환해서 출력시킨다.

 

또한 예외적으로 char배열은 println메서드로 출력하면 요소번호를 사용하지 않고도 각 요소를 바로 출력할 수 있다.(배열 요소간 구분자(,)는 생략하고 요소값만 연속으로 출력된다.) 이는 println메서드가 char배열일 때만 이렇게 동작하도록 만들어졌기 때문이다.

 


String배열과 String클래스

String 배열도 int배열과 생성하는 방법은 크게 다르지 않지만, 중요하게 다른 특징이 몇 가지 있다.

먼저 변수 생성후 값을 넣지 않으면 'null'값으로 초기화 된다.

※ 참고) 변수의 타입에 따른 기본값 정리

더보기
자료형 기본값
boolean false
char '\u0000'
byte, short, int 0
long 0L
float 0.0f
double 0.0d 또는 0.0
참조형 null

 

또  String은 프리미티브 타입인 int형과 다르게 논프리미티브 타입인 클래스이므로 원래라면 new연산자를 통해 객체를 생성해야 하지만 다른 객체들과 달리 특별히 String클래스만 new 연산자를 생략하여 간단히 표현하는 것이 허용된다.

아래의 String 배열은 출력시 모두 같은 결과값을 반환한다.

 

String[] name1 = new String[]{"Kim", "Park", "Yi"};

String[] name2 = {"Kim", "Park", "Yi"};  // new String 생략가능

String[] name3 = new String[3];
name3[0] = new String("Kim");
name3[1] = new String("Park");
name3[2] = new String("Yi");

String[] name4 = new String[3];          // new String 생략가능
name4[0] = "Kim";
name4[1] = "Park";
name4[2] = "Yi";

*결과 출력 : 
Kim
Park
Yi

 

사실 문자열이라는 용어는 '문자를 연이어 늘어놓은 것'을 의미하므로 문자배열인 char배열과 같은 뜻이다.

C언어에서는 문자열을 char배열로 다루지만, 객체지향언어인 자바에서는 char배열과 그에 관련된 메서드를 묶어서 클래스에 정의한다. 바로 String클래스이다. 한마디로 String클래스는 char배열에 여러가지 기능(메서드)를 추가한 것이다. 당연히 char배열을 사용하는 것보다 String클래스를 사용하는 것이 문자열을 다루기 더 편리하다. 단지 String객체(문자열)은 char배열과 달리 읽을 수 만 있을 뿐 내용을 변경할 수는 없다.

(변경 가능한 문자열을 다루려면, StringBuffer클래스를 사용하면 된다. 이에 대한 것은 문자열 편에서 따로 다루기로 한다.)

		String str = "Java";        // "Java"라는 문자열이 str에 저장됨
		str = str + "8";            // "Java8"이라는 새로운 문자열이 str에 저장됨
		System.out.println(str);    // Java8 출력

 

위의 문장에서 문자열 str의 내용이 변경되는 것 같지만, 실제로는 새로운 내용의 문자열이 생성되는 것이다. 문자열은 변경할 수 없기때문이다.

 


String클래스의 주요 메서드

여기서는 자주 사용하는 주요 메서드들만 간략하게 소개한다. 추후 String객체에 대해 다룰 일이 있을 때 더 자세하게 정리할 것이다.

메서드 설명
char charAt(int index) 문자열에서 해당 위치(index)에 있는 문자를 반환
int length() 문자열의 길이를 반환
String substring(int from, int to) 문자열에서 해당 범위(from~to)의 문자열을 반환 (to는 포함 안 됨)
boolean equals(Object obj) 문자열의 내용이 같은지 확인한다. 같으면 true, 다르면 false
char[] toCharArray() 문자열을 문자배열(char[])로 변환해서 반환

 

우리는 의식하지 않지만 사실 String클래스를 수시로 사용하고 있다. 이게 무슨 말이냐고?  main 메서드를 잘 보자.

 

public static void main(String[] args)

 

main 앞의 public static void는 제쳐두고 main메서드의 인자값으로 들어있는 String[] args는 무엇을 의미하는가?

그렇다. 바로 String타입의 배열([])을 가지고 있는 args라는 변수명을 main메서드의 인자값으로 가지고 있겠다는 것이다. 이것은 기본적으로 main메서드는 전달받을 때 문자열로 전달받는 것을 의미하며 main 메서드 내에서 출력되는 내용은 문자열로 출력되는 것을 알 수 있다.

이게 무엇을 의미하는 지는 추후에 다시 다루기로 하고, 여기서 다룰 것은 바로 main메서드 내에 args배열에 대한 접근 방식이다. args변수도 배열이니만큼, 각 요소에 접근이 가능하며, 커맨드 라인을 이용하여 매개변수 전달이 가능하다.

바로 프로그램을 실행할 때 클래스 이름 뒤에 공백문자로 구분하여 여러 개의 문자열을 프로그램에 전달하는 방법이다.

 

c:\jdk1.8\work\ch5>java 클래스명 abc 123 "Hello World"
// 매개변수는 공백으로 구분하기때문에 입력 문자열에 공백이 있는 경우에는 큰따옴표로 감사주어야 한다.

 

위의 커맨드 라인에 적은 abc, 123, "Hello World" 3개의 문자열이 String배열에 담겨서 클래스의 main메서드의 매개변수(args)에 전달된다. 그리고는 main메서드 내에서 args[0], args[1] args[2]과 같은 방식으로 커맨드 라인으로부터 전달받은 문자열에 접근할 수 있다.

 

public static void main(String[] args) {
	for(String str : args)
	System.out.println(str);
}
*결과 출력 : 
abc
123
Hello World

 

참고로 이클립스에서는 커맨드라인 매개변수 입력을 간단하게 할 수 있는 기능을 지원하고 있다.

Run메뉴 -> Run Configurations -> Arguments -> Program arguments에 커맨드라인에 입력하는 방식 그대로 입력하면 된다.

 


Arrays로 배열 다루기

Arrays클래스는 배열을 다루는 데 유용한 메서드들을 제공하는 데, 여기서는 중요한 메서드 몇 가지만 언급하고 넘어가겠다.

Arrays.toString(변수명) : 배열의 모든 요소를 문자열로 출력하는 메서드

Arrays.equals(변수1, 변수2) : 두 배열의 모든 요소를 비교하는 메서드. 같으면 true, 다르면 false 반환

Arrays.copyOf(변수명, 복사할 범위) : 배열 전체를 복사해서 새로운 배열을 만들어 반환

Arrays.copuOfRange(변수명, 시작위치, 끝위치) ; 배열의 일부를 복사해서 새로운 배열을 만들어 반환(끝위치-1)

Arrays.sort(변수명) : 배열을 정렬해서 반환

 

'백엔드 > Java' 카테고리의 다른 글

[Java] 자료 구조와 트리(Tree), 그래픽(Graph)  (0) 2023.12.27
[JAVA] JAVA 배열과 forEach문  (1) 2023.12.26
[Java] 2. 변수(Variable)  (0) 2023.07.31
[Java] 3. 주의해야할 연산자 특징들  (0) 2023.07.31
[Java] 1. 자바와 JVM  (0) 2023.07.31

댓글