개발 공부/Java & Spring

1. 배열(array)

빵다희 2022. 9. 7. 01:15
배열의 정의 

같은 타입의 여러 변수를 하나의 묶음으로 다루는 것을 '배열'이라고 한다.

똑같은 형식을 가진 많은 양의 데이터를 처리할 때, 배열을 사용하면 손쉽게 다룰 수 있다. 

배열에서 중요한 점은 '같은 타입'이어야 한다는 것이며, 서로 다른 타입의 변수들로 구성된 배열은 만들 수 없다.

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

 

배열의 선언과 생성
  • 배열 선언하는 방법 2가지
선언 방법 선언 예시
타입[] 변수이름; int[] score;
String[] name;
타입 변수이름[]; int score[];
String name[];

배열을 선언하는 것은 단지 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어졌을 뿐,

배열을 생성하기 위해서는 연산자 'new'와 함께 배열의 타입과 길이를 지정해 주어야 한다.

배열의 선언과 생성을 동시에 하면 아래와 같다.

int[] score = new int[5];     //  배열의 선언과 생성을 동시에. 길이가 5인 int 배열을 생성한다.

 

배열의 선언과 생성과정

1. int[] score; 선언

- int형 배열 참조변수 score를 선언한다. 데이터를 저장할 수 있는 공간은 아직 마련되지 않았다.

2. score = new int[5];

- 연산자 'new'에 의해서 메모리의 빈 공간에 5개의 int형 데이터를 저장할 수 있는 공간이 마련된다. 

- 그리고 각 배열 요소는 자동적으로 int의 기본값(default)인 0으로 초기화된다. (타입이 참조형인 경우에는 null로 초기화.)

- 끝으로 대입 연산자 '='에 의해 배열의 주소가 int형 배열 참조변수 score에 저장된다.(배열이 주소 0x100번지에 생성되었다고 가정.)

배열의 길이와 인덱스

생성된 배열의 각 저장공간을 '배열의 요소(element)'라고 하며, '배열 이름[인덱스]'의 형식으로 배열의 요소에 접근 가능하다.

인덱스(index)는 배열의 요소마다 붙여진 일련번호로 각 요소를 구별하는 데 사용된다. 인덱스의 범위는 0부터 '배열 길이-1'까지이다. 

예를 들어 길이가 5인 배열은 모두 5개의 요소를 가지며 인덱스의 범위는 0부터 (5-1), 4까지가 된다.

배열에서 4번째 요소를 읽어오는 식은 다음과 같다.

int value = score[3];    //  배열 score의 4번째 요소의 값을 읽어서 value에 저장. 

 

배열의 또 다른 장점은 index로 상수 대신 변수나 수식도 사용 가능하다는 것이다.

for문의 제어변수는 배열의 index로 사용하기에 딱 알맞아서, 배열을 다룰 때 for문은 거의 필수적이다. 

아래 두 식의 결과는 같다.  for문을 이용하여 배열의 값을 보다 간단히 변경할 수 있다. 

score[0] = 0;
score[1] = 10;
score[2] = 20;
score[3] = 30;
score[4] = 40;
 for(int i = 0; i < 5; i++){
    score[i] = i * 10;
}

※  index의 범위를 벗어난 값을 index로 사용하게 되면 코드 실행 시, 에러(ArrayIndexOutOfBoundsException)가 발생한다.

 

배열의 길이

배열의 길이는 배열의 요소의 개수, 값을 저장할 수 있는 공간의 개수다.

배열의 길이는 양의 정수이어야 하며, 최댓값은 int타입의 최댓값인  2의 31승 -1, 2,147,483,647이다.

길이가 0인 배열도 생성 가능하다.

 

배열이름.length

배열은 한번 생성하면 길이를 변경할 수 없기 때문에, 이미 생성된 배열의 길이는 변하지 않는다.

따라서 '배열이름.length'는 상수다. 값만 읽을 수 있을 뿐 변경할 수 없다. 코드의 관리와 new인자를 통해 배열이 재생성되는 등 유효한 인덱스의 범위를 넘어서는 인덱스를 호출하여 발생하는 에러를 방지하기 위해for문을 포함하여, 모든 케이스에 배열의 길이를 직접 적어주는 것보다 '배열이름.length'를 사용하는 것이 좋다.

 

배열의 초기화

배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 따로 초기화를 해주지 않아도 되지만, 배열을 간단히 초기화 할 수 있는 방법은 아래와 같다. 

  • 일반 초기화
int[] score = new int[]{50, 60, 70, 80, 90};  //  배열의 생성과 초기화를 동시에 
int[] score = {50, 60, 70, 80, 90};   //  new int[]를 생략가능하다. 
  • 매개변수일 때의 초기화
int result = add(new int[]{100, 90, 80, 70, 60});  // ok
int result = add({100, 90, 80, 70, 60});                  //  에러발생. new int[]를 생략할 수 없음.
  • 길이가 0인 배열 생성
int[] score = new int(0);
int[] score = new int[]{};
int[] score = {};

 

배열의 출력 

배열을 출력할 때 for문을 이용하여 각 요소마다 출력하는 방법도 있지만 더 간단한 방법은 'Arrays.toString(배열이름)'메소드를 사용하는 것이다. (*toString을 사용하려면 'import java.util.*;'를 추가해야 한다. )

그냥 배열을 바로 출력하면 '타입@주소'의 형식으로 출력된다. 

예외적으로 char배열은 print, println 메소드로 출력하면 각 요소가 구분자 없이 그대로 출력된다. 

예시 ) char[] chArr = {'a','b','c','d'};

System.out.println(chArr);    //  abcd 출력.

 

배열의 복사 

배열은 한번 생성하면 그 길이를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다면 큰 배열을 새로 만들고 이전 배열로부터 내용을 복사해야 한다. 배열을 복사하는 방법은 아래와 같다.

  • for문을 이용한 복사
int arr = new int[5];                        // 1. 배열 생성
int[] tmp = new int[arr.length*2]; // 2. arr 배열을 복사해올 배열을 생성 이전 배열의 두배만큼 길이를 준다.
for(int i = 0; i<arr.length; i++){ 
   tmp[i] = arr[i];                              // 3. for문을 이용해서 배열 arr의 모든 요소에 저장된 값을 하나씩 배열 tmp에 복사한다.
}
arr = tmp;                                        // 4. 참조변수 arr에 참조변수 tmp의 값을 저장한다. arr의 값은 바뀌고 arr는 배열 tmp를 가리키게 된다. 
  • System.arraycopy()를 이용한 복사 

배열의 요소 하나하나에 접근하여 복사하는 for문과는 달리 지정된 범위의 값을 통째로 복사하는 arraycopy()가 더 효율적이다.

System.arraycopy(원본 배열의 이름, 원본 배열 복사 시작 인덱스, 복사될 배열 이름, 복사받은 배열의 시작 인덱스, 원본 배열에서 복사할 개수);

 

객체 배열 

아래는 String 배열을 하나 생성했을 때, 배열의 구조도이다.

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

배열에 실제 객체가 아닌 객체의 주소가 저장되어있다. 이처럼, 기본형 배열이 아닌 경우, 즉 참조형 배열의 경우 배열에 저장되는 것은 객체의 주소이고, 참조형 배열을 객체 배열이라고도 한다. 

 

char배열과 String클래스

문자 배열인 char배열 과 String 타입의 변수는 사실 같은 의미이다. 

그런데 자바에서는 char배열이 아닌 String클래스를 이용해서 문자열을 처리하는 이유는 String클래스가 char배열에 여러 가지 기능을 추가하여 확장한 것이기 때문이다. 그래서 char배열을 사용하는 것보다 String클래스를 사용하는 것이 문자열을 다루기 더 편리하다.

단, char배열과 String클래스의 한 가지 중요한 차이가 있는데 String객체는 읽을 수만 있을 뿐 내용을 변경할 수 없다. (* StringBuffer클래스를 사용하면 문자열이 변경 가능하다.)

String str = "Zzang";
str = str + "Heeya";       // str의 값이 변경되는 게 아닌 "ZzangHeeya"라는 새로운 문자열이 str에 저장된다.
System.out.println(str);  // "ZzangHeeya"

 

String클래스의 주요 메서드
메서드 설명
char charAt(int index) 문자열에서 해당 인덱스에 있는 문자반환.
int length() 문자열 길이 반환
String substring(int from, int to) 문자열에서 해당범위(from~to)에 있는 문자열반환, to는 범위 미포함
boolean equals(Object obj) 문자열의 내용이 obj와 같은지 확인하여 결과값 반환
대소문자를 구분하지 않고 비교하려면 equalsIgnoreCase() 사용
char[]toCharArray() 문자열을 문자배열(char[])로 변환해서 반환.
728x90
반응형