자바 배열에 대해 알아보자

2025. 1. 29. 19:16JAVA

728x90
반응형

 

 안녕하세요. 진득 코딩입니다.

 

최근 자바 포스팅을 잠시 멈추고 HTML/CSS 포스팅을 하다가 오랜만에 자바 포스팅으로 돌아왔습니다.

 저번 시간에는 조건문에 대해서 알아보았습니다.

 

 이때까지 사용하던 변수들은 적은 숫자일 때는 상관이 없지만 변수의 개수가 많아지면 다루기 힘들어지게 됩니다.

 

 이번 시간에는 같은 타입의 여러 변수를 하나의 묶음으로 다루는 '배열(array)'에 대해 알아보도록 하겠습니다.

 

 배열(array)

 

  • 배열(array)이란 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것을 의미합니다.

  • 배열을 사용하면 많은 양의 데이터를 손쉽게 다룰 수 있습니다.


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

 

  • 이때 배열에 포함된 변수들은 같은 타입이어야 합니다.

배열의 선언과 생성

 

  • 배열을 선언하는 방법은 원하는 타입의 변수를 선언하고 변수 또는 타입에 배열임을 의미하는 대괄호 []를 붙이면 됩니다.

선언 방법 선언 예
 타입[] 변수이름;  int[] score;
 String[] name;
 타입 변수이름[];  int score[];
 String name[];

 

  • 배열을 선언한 다음에는 배열을 생성해야 합니다.

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

  • 이때 배열을 생성해야만 비로소 값을 저장할 수 있는 공간이 만들어집니다.

  • 연산자 'new'와 함께 배열의 타입과 길이를 지정해주어야 합니다.


 타입[] 변수이름; // 배열을 선언(배열을 다루기 위한 참조변수 선언
 변수이름 = new 타입[길이]; //배열을 생성(실제 저장공간을 생성)

 

길이가 5인 int 배열 생성

 

  • 위 코드는 길이가 5인 int 배열을 생성합니다.

배열의 선언과 생성

 

  • 위 코드와 같이 배열의 선언과 생성을 동시에 하면 간략히 한 줄로 할 수 있습니다.

  • 배열의 선언과 생성 과정을 단계별로 살펴보겠습니다.

  1. int[] score;
     - int형 배열 참조변수 score을 선언합니다.

     - 데이터를 저장할 수 있는 공간은 아직 마련되지 않았습니다.

  2. score = new int[5];
     - 연산자 'new'에 의해서 메모리의 빈 공간에 5개의 int형 데이터를 저장할 수 있는 공간이 마련됩니다.

     - 각 배열 요소는 자동적으로 int의 기본값(default)인 0으로 초기화됩니다.

     - 대입 연산자 '='에 의해 배열의 주소가 int형 배열 참조변수 score에 저장됩니다.

     - 이 배열은 '길이가 5인 int 배열'이며, 참조변수의 이름을 따서 '배열 score'라고 부릅니다.

배열의 길이와 인덱스

 

  • 배열의 요소(element)는 생성된 배열의 각 저장공간을 의미합니다.

  • 인덱스(index)는 배열의 요소마다 붙여진 일련번호를 의미합니다.

  • 이때 인덱스는 1이 아닌 0부터 시작합니다.


 인덱스(index)의 범위는 0부터 '배열길이-1'까지

 

  • 배열에 값을 저장하고 읽어오는 방법은 변수와 같지만 변수이름 대신 '배열이름[인덱스]'를 사용합니다.

  • 배열의 또 다른 장점은 index로 상수 대신 변수나 수식도 사용할 수 있습니다.

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

  • 괄호[] 안에 수식이 포함된 경우, 이 수식이 먼저 계산됩니다.

  • 그래야 배열의 몇 번째 요소인지 알 수 있기 때문입니다.

  • 배열을 다룰 때 주의할 점은 index의 범위를 벗어난 값을 index로 사용하지 않아야 한다는 것입니다.

  • 유효한 범위를 벗어난 값을 index로 사용하는 것은 배열을 다룰 때 하는 가장 흔한 실수입니다.

  • 이때 컴파일러는 배열의 index로 변수를 사용했을 때 변수의 값은 실행 시에 대입되므로 이 값의 범위를 확인할 수 없어 이러한 실수를 걸러주지 못합니다.

  • 그래서 유효한 범위의 값을 index로 사용하는 것은 전적으로 프로그래머의 책임입니다.

  • 이때 유효하지 않은 값을 index로 사용하면, 실행 시에 에러(ArrayIndexOutOfBoundsException)가 발생합니다.

예제 5-1
예제 5-1 console 출력

 

  • 배열 score는 길이가 5이므로 index의 범위가 0~4이지만, 일부러 이 범위에 속하지 않는 7을 배열의 index로 해서 값을 출력해 보았습니다.

  • 컴파일 시에는 아무런 문제가 없지만, 실행 시에는 아래와 같은 에러가 발생합니다.


 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7 at   ch5.ArrayEx01.main(ArrayEx01.java:22)

 

  • 위 메시지는 배열의 인덱스가 유효한 범위를 넘었다는 뜻입니다.

배열의 길이

 

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

길이가 0인 배열

 

  • 배열의 길이는 양의 정수이어야 하며 최댓값은 int타입의 최댓값, 약 20억입니다.

  • 배열의 길이는 거의 제약이 없다고 볼 수 있습니다.


 배열의 길이는 int 범위의 양의 정수(0도 포함)이어야 합니다.

 

배열이름.length

 

  • '배열이름.length'를 통해서 배열의 길이에 대한 정보를 얻을 수 있습니다.

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

  • 따라서 '배열이름.length'는 상수입니다.

  • 배열의 길이가 바뀔 때 for문에 있는 조건식에 있는 배열의 길이를 고민하지 않기 위해서 배열의 길이를 직접 적어주는 것보다 '배열이름.length'를 사용하는 것이 좋습니다.

  • '배열이름.length'는 배열의 길이가 변경되면 자동적으로 변경된 배열의 길이를 값으로 갖기 때문에, 배열과 함께 사용되는 for문의 조건식을 일일이 변경해주지 않아도 됩니다.

배열의 길이 변경하기

 

  • 배열에 저장할 공간이 부족한 경우에는 더 큰 길이의 새로운 배열을 생성한 다음, 기존의 배열에 저장된 값들을 새로운 배열에 복사하면 됩니다.


 배열의 길이를 변경하는 방법 :
 1. 더 큰 배열을 새로 생성한다.
 2. 기존 배열의 내용을 새로운 배열에 복사한다.

 

  • 이러한 작업들은 꽤나 비용이 많이 들기 때문에, 처음부터 배열의 길이를 넉넉하게 잡아줘서 새로 배열을 생성해야 하는 상황이 가능한 적게 발생하도록 해야 합니다.

  • 기존의 2배 정도의 길이로 생성하는 것이 좋습니다.

배열의 초기화

 

  • 배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 배열을 사용하기 전에 따로 초기화를 해주지 않아도 됩니다.

  • 하지만 원하는 값을 저장하려면 아래와 같이 각 요소마다 값을 지정해줘야 합니다.


 int[] score = new int[5]; //길이가 5인 int형 배열을 생성한다.
 score[0] = 50; //각 요소에 직접 값을 저장한다.
 score[1] = 60;
 score[2] = 70;
 score[3] = 80;
 score[4] = 90;

 

  • 하지만 자바에서는 다음과 같이 배열을 간단히 초기화할 수 있습니다.

배열의 생성과 초기화를 동시에

 

  • 괄호 {} 안의 값의 개수에 의해 배열의 길이가 자동으로 결정되기 때문에 괄호 [ ] 안에 배열의 길이는 안 적어도 됩니다.

new int[] 생략

 

  • 심지어 위와 같이 'new 타입[]'을 생략하여 코드를 더 간단히 할 수도 있습니다.

메서드 호출 시 new 생략 불가

 

  • 위와 같이 매개변수로 int 배열을 받는 add 메서드가 정의되어 있고, 이 메서드를 호출해야 할 경우 역시 'new 타입[]'을 생략할 수 없습니다.

  • 괄호 {} 안에 아무것도 넣지 않으면, 길이가 0인 배열이 생성됩니다.

  • 참조변수의 기본 값은 null이지만, 배열을 가리키는 참조변수는 null 대신 길이가 0인 배열로 초기화하기도 합니다.

배열의 출력

 

  • 배열에 저장된 값을 확인할 때에 다음과 같이 for문을 사용하면 됩니다.

배열의 출력

 

  • 아래와 같이 'Arrays.toString(배열이름)' 메서드를 사용하게 되면 더 간단합니다.

Arrays.toString 메서드

 

  • 이 메서드는 배열의 모든 요소를 '[첫번째 요소, 두 번째 요소, ...]'와 같은 형식의 문자열로 만들어서 반환합니다.

예제 5-2

 

  • iArr의 값을 바로 출력하면 '타입@주소'의 형식으로 출력됩니다.

  • '[I'는 1차원 int 배열이라는 의미이고, '@' 뒤에 나오는 16진수는 배열의 주소인데 실제 주소가 아닌 내부 주소입니다.

  • 예외적으로 char 배열은 println 메서드로 출력하면 각 요소가 구분자 없이 그대로 출력되는데, 이것은 println 메서드가 char 배열일 때만 이렇게 동작하도록 작성되었기 때문입니다.

배열의 복사

 

  • 배열은 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 내용을 복사해야 합니다.

  • 배열을 복사하는 두 가지가 있는데 먼저 for문을 이용해서 배열을 복사하는 방법을 살펴보겠습니다.

for문을 이용한 배열 복사

 

  •  위 과정을 단계별로 살펴보겠습니다.

  1. 배열 arr의 길이인 arr.length의 값이 5이므로 길이가 10인 int 배열 tmp가 생성되고, 배열 tmp의 각 요소는 int의 기본값인 0으로 초기화됩니다.

  2. for문을 이용해서 배열 arr의 모든 요소에 저장된 값을 하나씩 배열 tmp에 복사합니다.

  3. 참조변수 arr에 참조변수 tmp의 값을 저장합니다. arr은 배열 tmp를 가리키게 됩니다.

  4. 결국 참조 변수 arr과 tmp는 같은 배열을 가리키게 됩니다.

  5. 즉, 배열 arr과 배열 tmp는 이름만 다를 뿐 동일한 배열입니다.

  6. 그리고 전에 arr이 가리키던 배열은 더 이상 사용할 수 없게 됩니다.

    * 배열은 참조변수를 통해서만 접근할 수 있기 때문에, 자신을 가리키는 참조변수가 없는 배열은 사용할 수 없습니다. 이렇게 쓸모없게 된 배열은 JVM의 가비지 컬렉터에 의해서 자동적으로 메모리에서 제거됩니다.

예제 5-3
예제 5-3 console 출력

 

  • 배열의 복사에 대해 살펴볼 수 있는 예제입니다.

System.arraycopy()를 이용한 배열의 복사

 

  • for문 대신 System 클래스의 arraycopy()를 사용하면 보다 간단하고 빠르게 배열을 복사할 수 있습니다.

  • arraycopy()는 지정된 범위의 값들을 한 번에 통째로 복사합니다.


 배열의 복사는 for문보다 System.arraycopy()를 사용하는 것이 효율적이다.

 

  • arraycopy()를 호출할 때는 어느 배열의 몇 번째 요소에서 어느 배열로 몇 번째 요소로 몇 개의 값을 복사할 것인지 지정해줘야 합니다.

예제 5-4

 

  • 배열 abc와 num로 num의 값을 자유롭게 바꾸는 예제입니다.

배열의 활용

 

예제 5-5

 

  • for문을 이용해서 배열에 저장된 값을 모두 더한 결과를 배열의 개수로 나누어서 평균을 구하는 예제입니다.

예제 5-6

 

  • 배열에 저장된 값 중에서 최댓값과 최솟값을 구하는 예제입니다.

  • 반복문을 통해서 배열의 두 번째 요소'score[1]'부터 max와 비교하기 시작합니다.

  • 만일 배열에 담긴 값이 max에 저장된 값보다 크다면, 이 값을 max에 저장합니다.

  • 최솟값 min도 같은 방식으로 얻을 수 있습니다.

예제 5-7

 

  • random()을 이용해서 배열의 임의의 위치에 있는 값과 배열의 첫 번째 요소인 'numArr[0]'의 값을 교환하는 일을 100번 반복합니다.

  • 해당 알고리즘은 중복된 값이 없는 배열에서 값들의 위치만 서로 바꾸는 것이므로 중복된 값이 나올 수가 없습니다.

예제 5-8

 

  • 로또 번호를 생성하는 예제입니다.

  • 배열의 인덱스가 i인 값(ball[i])과 random()에 의해서 결정된 임의의 위치에 있는 값과 자리를 바꾸는 것을 6번 반복합니다.

  • 마치 1부터 45까지의 번호가 쓰인 카드를 잘 섞은 다음 맨 위의 6장을 꺼내는 것과 같다고 볼 수 있습니다.

예제 5-9

 

  • 불연속적인 범위의 값들로 배열을 채우는 것은 배열을 하나 더 사용하면 됩니다.

  • 먼저 배열 code에 불연속적인 값들을 담고, 임의로 선택된 index에 저장된 값으로 배열 arr의 요소들을 하나씩 채우면 됩니다.

예제 5-10

 

  • 길이가 10인 배열에 0과 9 사이의 임의의 값으로 채운 다음, 버블정렬 알고리즘을 통해서 크기순으로 정렬하는 예제입니다.

  • 배열의 길이가 n일 때, 배열의 첫 번째부터 n-1까지의 요소에 대해, 근접한 값과 크기를 비교하여 자리바꿈을 반복합니다.
  • 보다 효율적인 작업을 위해 changed라는 boolean형 변수를 두어서 자리바꿈이 없으면 break문을 수행하여 정렬을 마치도록 하였습니다.
  • 배열에 대해 좀 더 알아보고 싶으면 밑에 있는 주소를 통해 살펴볼 수 있습니다.

https://jinco.tistory.com/52

 

[정보처리기사] 여러 종류의 정렬(Sort)에 대해 알아보자

안녕하세요. 진득코딩입니다. 프로그래밍을 꿈꾸는 사람들에게 가장 무난하고 보편적인 자격증은 정보처리기사 자격증이라고 생각합니다.  이번 시간에는 정보처리기사의 시험 범위에 포함

jinco.tistory.com

 

예제 5-11

 

  • 길이가 10인 배열을 만들고 0과 9 사이의 임의의 값으로 초기화합니다.

  • 이 배열에 저장된 각 숫자가 몇 번 반복해서 나타나는지를 세어서 배열 counter에 담은 다음 화면에 출력합니다.


 

 이렇게 많은 데이터를 다룰 때 편리한 배열에 대해 알아보았습니다.

 

 배열은 위에 있는 활용에서 살펴본 것처럼 여러 방면으로 사용할 수 있기 때문에 더 많은 예제를 통해 익숙해지는 것이 좋다고 생각합니다.

 

 이번 포스팅은 여기까지입니다.

 

 궁금하신 사항이나 문의하실 사항은 댓글을 남겨주시면 열심히 답글 달도록 하겠습니다.

 

 끝까지 봐주셔서 감사합니다.😊

728x90
반응형
LIST