[Java] 자바 배열(Array) 기본 개념 | 선언, 생성, 차원, 정렬, ArrayList

이 글은

〈[되기] 코딩 테스트 합격자 되기(자바 편)〉

[Must Have] 이재환의 자바 프로그래밍 입문

에서 발췌했습니다.

골든래빗 출판사
김희성, 이재환 지음

배열은 복수의 동일한 자료형의 변수를 묶어놓은 자료구조입니다. 대량의 데이터를 다룰 때나 차례대로 읽어들이고 싶을 때 사용합니다. 자바의 배열을 알아보고, 배열을 다룰 때 사용하는 Array 클래스를 알아봅시다.

[Java] 자바 배열(Array) 기본 개념 | 선언, 생성, 차원, 정렬, ArrayList

 

1. 배열 선언

프로그래밍을 하다 보면 자료형이 같은 자료를 여러 개 반복해서 구현해야 하는 일이 생깁니다. 가령 우리 학교 한 반의 국어 점수를 기록하고 싶습니다. 반의 인원은 50명입니다. 코드로 작성하면 다음과 같이 될 겁니다.

 

int korScore01 = 90;
int korScore02 = 80;
int korScore03 = 70;
int korScore04 = 95;
…
int korScore49 = 85;
int korScore50 = 99;

 

변수 선언이 너무 많습니다. 당연히 비효율적이고 불편합니다. 이런 때는 변수를 각각 선언하여 점수를 저장하는 것보다 한 번에 여러 점수를 저장할 수 있는 기능이 필요합니다. 이럴 때 사용하는 것이 배열입니다.

배열 변수는 기본 자료형을 사용하더라도 다음과 같이 객체를 만드는 방법으로 선언합니다.

 

 

그러므로 앞에서 사용한 변수 50개를 배열 변수 하나로 다음과 같이 선언할 수 있습니다.

 

 

① korScore라고 변수명을 만듭니다.

② 자료형은 int로 합니다. 그리고 변수가 일반 변수가 아니고 배열이라고 [ ] 표시를 합니다.

③ 객체를 만듭니다.

④ 객체의 자료형은 int형으로 합니다.

⑤ 데이터 50개를 저장할 공간을 만듭니다.

 

이렇게 int형 데이터 50개를 저장할 공간을 힙에 만들고 korScore는 해당 공간을 가리킵니다. 배열 요소를 구분하는 배열 인덱스는 0부터 시작합니다. 다음 그림으로 다시 이해해보도록 합니다.

 

 

일상에서 그냥 0호라고 말하면 어느 집의 0호인지 알 수 없습니다. 그래서 우리는 한아름빌라 0호, 한아름빌라 1호 이런 식으로 얘기합니다. 이러면 다른 사람도 어느 건물의 몇 호를 얘기하는지 알 수 있습니다.

배열도 마찬가지입니다. korScore는 저 한아름빌라가 건물을 가리키듯 배열을 가리킵니다. 각 요소를 가리키기 위해서는 한아름빌라 0호 대신 korScore[0] 이런 식으로 대괄호 [ ] 안에 인덱스를 써주면 됩니다.

이제 접근 방식을 알았으니 사용은 다음과 같이 합니다. 배열 표시인 대괄호 [ ] 사이에 인덱스 값을 숫자로 입력하여 하나 하나의 배열의 요소를 변수로 사용할 수 있습니다.

 

korScore[0] = 90;
korScore[1] = 80;
…
korScore[49] = 99;

 

이처럼 배열은 똑같은 자료형을 저장하기 위한 겁니다. 자료형은 기본 자료형부터 사용자가 만든 클래스까지 다양하므로 자료형을 적어주고 대괄호를 통해서 배열 표시를 해주고 생성할 때 몇 개인지 알려주면 됩니다. 그리고 배열 인덱스를 이용하여 개별 요소에 접근해서 사용하면 됩니다.

일반 변수처럼 변수 먼저 선언하고 나중에 대입을 시켜줄 수도 있습니다.

 

 

class BoxA1 { // ①

}

public class Ex01_ArrayInstance
{
   public static void main(String[] args)
   {
       // 길이가 5인 int형 1차원 배열 생성
       int[] ar1 = new int[5];
       
       // 길이가 7인 double형 1차원 배열 생성
       double[] ar2 = new double[7];
       
       // 배열의 참조 변수와 객체 생성 분리
       float[] ar3;
       ar3 = new float[9];
       
       // 객체 대상 1차원 배열
       BoxA1[] ar4 = new BoxA1[5];
       
       // 배열의 객체 변수 접근 / 메서드 사용
       
      System.out.println("배열 ar1 길이: " + ar1.length); // ②
      System.out.println("배열 ar2 길이: " + ar2.length);
      System.out.println("배열 ar3 길이: " + ar3.length);
      System.out.println("배열 ar4 길이: " + ar4.length);
   }
}

 

▼ 실행 결과

 

① BoxA1을 정의합니다. 이렇게 필드와 메서드가 없어도 클래스는 맞습니다. 생성된 배열은 객체이기 때문에 멤버를 가지고 있습니다. 자바에서는 배열을 사용하기 쉽게 이미 몇 가지의 편리한 멤버(메서드 및 필드)를 만들어놓았습니다. 그중 하나가 length 멤버 변수입니다.

②처럼 현재 이 배열 객체는 몇 개의 요소를 가지고 있는지 ar1.length처럼 멤버 변수 length를 통해 알 수 있습니다.

 

1.1 1차원 배열

1차원 배열은 가장 간단한 배열 형태를 가집니다. “간단하다”라고 말한 이유는 1차원 배열의 모습이 메모리에 할당된 실제 배열의 모습과 같다는 겁니다. 다음 그림을 보면 쉽게 이해할 수 있습니다.

 

 

왼쪽 그림이 1차원 배열의 모습이고, 오른쪽 모습이 실제 메모리에 배열이 할당된 모습입니다. 배열의 각 데이터는 메모리의 낮은 주소에서 높은 주소 방향으로 연이어 할당됩니다.

 

2. 배열 사용

2.1 기본 자료형

int형 배열을 만들고 값을 대입하고 참조하는 방법을 예제로 살펴봅니다.

 

public class Ex02_intArray
{
   public static void main(String[] args)
   {
       // 길이가 3인 int형 1차원 배열의 생성
       int[] ar = new int[3]; // ①
      
       ar[0] = 100; // ② 값의 저장 : 첫 번째 요소
       ar[1] = 90; // 값의 저장 : 두 번째 요소
       ar[2] = 80; // 값의 저장 : 세 번째 요소
      
       int sum = ar[0] + ar[1] + ar[2]; // 3 값의 참조
       System.out.println("총점 : " + sum);
   }
}

 

▼ 실행 결과

 

① int형 데이터를 저장할 배열을 선언합니다.

② 배열 요소에 접근합니다. 배열 요소는 일반 변수처럼 사용합니다. 값을 저장합니다.

③ 배열 요소에서 값을 참조해옵니다.

 

2.2 String형

String형 배열을 만들고 값을 대입하고 참조하는 방법을 예제로 살펴봅시다.

 

public class Ex03_StringArray
{
   public static void main(String[] args)
   {
       String[] name = new String[7]; // ①
       
       name[0] = new String("홍길동");  // ②
       name[1] = new String("전우치");
       name[2] = new String("손오공");
       name[3] = new String("강감찬");
       name[4] = new String("이순신");
       name[5] = new String("을지문덕");
       name[6] = new String("양만춘");
       
       int cnum = 0;
       
       for(int i = 0; i < name.length; i++) { // ③
           System.out.println(name[i]); // ④
           cnum += name[i].length(); // ⑤
       }
       
       System.out.println("총 문자의 수: " + cnum); // ⑥
   }
}

 

▼ 실행 결과

 

① String형 데이터를 저장할 배열을 선언합니다.

② 문자열 리터럴로 대입하지 않고 new 연산자를 이용하여 새로운 문자열 객체를 만들어 변수에 대입하고 있습니다.

③ 배열 name의 요소 개수만큼 반복문으로 반복합니다. ④배열의 개별 요소에 저장된 값을 출력합니다. ⑤ 배열의 개별 요소에 저장된 값은 문자열입니다. 각 문자열의 길이를 구해서 더해줍니다.

⑥ name 배열에 저장되어 있는 모든 문자열의 총 길이를 출력합니다.

 

반복문에서 ⑤를 첫 번째만 풀어보면 다음과 같습니다.

 

cnum += name[i].length();
            ↓
cnum = cnum + name[i].length();
       ↓      ↓
cnum = 0 + "홍길동".length();
           ↓
cnum = 0 + 3;

 

2.3 클래스형

클래스형 배열을 만들고 값을 대입하고 참조하는 방법을 예제로 살펴봅시다.

 

class BoxA4 {
    public String name;
    
    BoxA4(String name) {
        this.name = name;
    }
}

public class Ex04_BoxArray
{
    public static void main(String[] args)
    {
        BoxA4[] ar = new BoxA4[3]; // ①
        
        // 2 배열에 객체 저장 (초기화)
        ar[0] = new BoxA4("홍길동");
        ar[1] = new BoxA4("전우치");
        ar[2] = new BoxA4("손오공");
        
        // 3 저장된 객체의 참조
        System.out.println(ar[0].name);
        System.out.println(ar[1].name);
        System.out.println(ar[2].name);
    }
}

 

▼ 실행 결과

 

① BoxA4형 객체를 저장할 배열을 선언합니다.

② BoxA4 클래스의 생성자를 이용해 객체를 만들고 배열의 개별 요소에 객체의 참조 값을 대입합니다.

③ 객체의 참조 변수 ar[0]을 통해서 객체에 접근해 멤버 변수의 값을 가져와서 출력합니다.

 

2.4 매개변수, 반환형

배열은 일반 변수처럼 메서드의 매개변수로 사용할 수도 있고 메서드의 반환형으로도 사용할 수 있습니다.

 

public class Ex05_ArrayInMethod
{
    public static void main(String[] args)
    {
        int[] arr = makeIntArray(5); // 1
        
        int sum = sumOfArray(arr); // 2
        
        System.out.println(sum);
        
    }
    
    public static int[] makeIntArray(int len) // 3
    {
        int[] arr = new int[len]; // 4
        for(int i=0; i< len; i++)
        {
            arr[i] = i;
        }
        return arr; // 5
    }
    
    public static int sumOfArray(int[] arr)
    {
        int sum = 0;
        for(int i=0; i< arr.length; i++) // 6
        {
            sum = sum + arr[i]; // 7
        }
        return sum;
    }
}

 

▼ 실행 결과

 

③ 메서드의 반환형이 int형 배열입니다. ④ 매개변수로 들어온 값으로 배열 개수를 정합니다. ⑤ 배열 전체를 가리킬 때는 배열의 이름만 이용합니다. 앞의 예시에서 “한아름빌라”하고 건물의 이름만 얘기하는 것과 같습니다.

① makeIntArray(5) 메서드 자리에 반환된 배열 객체가 들어오게 됩니다. 그리고 선언된 배열 변수에 해당 객체의 참조 값이 대입됩니다. ② 배열을 인수로 넘겨줄 수도 있습니다. 역시 배열 전체를 가리키기 때문에 이름만 사용합니다.

⑥ 배열의 요소 개수만큼 반복문을 실행합니다. ⑦ 배열의 요소별 접근은 인덱스값을 이용해서 객체를 참조하게 됩니다.

 

2.5 배열 생성과 동시에 초기화

앞의 예제는 배열을 선언하고, 배열의 요소에 개별적으로 접근해 값을 대입했지만, 배열은 생성과 동시에 초기화를 할 수도 있습니다.

 

배열 생성

int[] arr = new int[3];

 

배열 생성 및 초기화 1

int[] arr = new int[ ] { 1, 2, 3 };

 

배열 생성 및 초기화 2

int[] arr = { 1, 2, 3 };

 

뒤에 초기화하는 데이터 개수를 보고 생략된 숫자를 알 수 있습니다. 뒤에 초기화하는 데이터를 보고 당연히 배열의 초기화 값이라고 생각할 수 있습니다. 이처럼 자바 컴파일러가 유추할 수 있는 부분은 생략이 가능합니다.

그리고 배열의 값을 초기화하지 않았을 때도 디폴트 초기화는 진행됩니다. 기본 자료형 배열은 모든 요소를 0으로 초기화되고, 객체 배열(참조 변수 배열)은 모든 요소가 null로 초기화됩니다.

 

class BoxA6 { } // 1

public class Ex06_ArrayInit
{
    public static void main(String[] args)
    {
        int[] arr1 = new int[3]; // 2 0으로 초기화
        int[] arr2 = new int[] {1, 2, 3}; // 3
        double[] arr3 = {1.0, 2.0, 3.0}; // 4
        double[] arr4 = new double[3]; // 5 0.0으로 초기화
        BoxA6[] arr5 = new BoxA6[3];
        
        for (int i=0; i<arr1.length; i++)
        {
            System.out.print(arr1[i] + " ");
            System.out.print(arr2[i] + " ");
            System.out.print(arr3[i] + " ");
            System.out.print(arr4[i] + " ");
            System.out.print(arr5[i] + " ");
            System.out.println();
        }
    }
}

 

▼ 실행 결과

 

① BoxA6을 정의합니다. 이렇게 필드와 메서드가 없어도 클래스는 맞습니다.

① BoxA6을 정의합니다. 이렇게 필드와 메서드가 없어도 클래스는 맞습니다.

③ 뒤에 초기화하는 데이터 개수로 숫자를 파악할 수 있으므로 대괄호 안의 숫자를 생략할 수 있습니다.

④ 뒤에 초기화하는 데이터 개수로 배열임을 알 수 있고 숫자를 파악할 수 있으므로 객체의 배열 생성 부분을 생략할 수 있습니다.

⑤ 기본 자료형은 별도의 초기화를 하지 않아도 초기화됩니다. double형이므로 0.0으로 초기화됩니다.

 

2.5 main() 메서드의 매개변수

이제 main() 메서드에 사용된 매개변수도 이해할 수 있게 되었습니다.

 

public static void main(String[] args)
{
    ...
}

 

다만 main() 메서드는 개발자가 직접 호출하는 메서드가 아니고 JVM이 프로그램을 실행할 때 불리는 메서드입니다.

그래서 메서드를 호출해 인수를 넘겨주는 방식이 아니고 ‘명령 프롬프트’에서 프로그램을 실행할 때 인수를 넘겨주거나 이클립스에서는 다음에서 하는 방법으로 인수를 넘겨주어야 테스트를 할 수 있습니다.

명령행에서 다음과 같이 실행하면 JVM이 내부적으로 배열을 만들어서 main() 메서드에 넘겨주게 됩니다.

 

C:\JavaStudy> java Simple Apple Banana Orange

String[] arr = new String[] {“Apple”, “Banana”, “Orange” };
main(arr);

 

예제를 만들어서 매개변수로 들어오는 배열의 값을 확인해보겠습니다.

 

(1) Ex07_mainParameter 클래스를 다음과 같이 작성합니다.

public class Ex07_mainParameter
{
    public static void main(String[] args)
    {
        // main() 메서드의 매개변수 확인
        for(int i = 0; i < args.length; i++ )
            System.out.println(args[i]);
    }
}

 

(2) 일단 이클립스에서 실행해봅니다. 아무런 결과가 출력되지 않습니다. 매개변수가 입력되지 않았기 때문입니다.

 

(3) main() 메서드에 매개변수를 넘겨주려면 프로젝트 탐색기창에서 ① 클래스를 선택하고 메뉴에서 ②[Run] → ③[Run Configurations …]를 선택합니다.

 

(4) 우측의 탭에서 ① [Arguments] 탭을 선택하고 ② [Program arguments]에 apple banana orange 이렇게 매개변수로 사용할 데이터를 입력합니다. 그리고 하단의 ③ [Run]을 선택합니다.

 

실행 결과는 다음과 같습니다. main() 메서드에 매개변수가 잘 전달되었음을 확인할 수 있습니다.

 

▼ 실행 결과

 

이제 이클립스에서 그냥 실행만 해도 이 클래스의 실행은 저 값이 계속 출력됩니다. 프로그램을 실행할 때마다 조금 전에 입력한 값이 매개변수로 main()에 전달되기 때문입니다. 더 이상 매개변수의 전달이 필요 없으면 아까와 같이 창을 열어서 매개변수를 지워주면 됩니다.

 

3. for ~ each문

배열을 이용한 반복문을 사용하다 보면 for문 안에 항상 배열 길이만큼 반복을 하는 코드를 작성하게 됩니다. 이 부분은 컴파일러가 유추할 수 있는 부분입니다. 그래서 배열과 for문을 같이 사용할 때는 다음과 같은 기능을 제공해주고 있습니다. ‘향상된 기능의 for문’이라고 부릅니다.

 

public class Ex08_EnhancedFor
{
    public static void main(String[] args)
    {
        int[] arr = {1, 2, 3, 4, 5}; // ①
        
        // ② 배열 요소 전체 출력
        for(int e: arr) {
            System.out.print(e + " ");
        }
        System.out.println(); // 줄바꿈을 목적으로
        
        
        int sum = 0;
        
        // 배열 요소의 전체 합 출력
        for(int e: arr) {
            sum = sum + e;
        }
        System.out.println("sum: " + sum);
    }
}

 

▼ 실행 결과

 

① 배열의 초기화 값이 주어져 있으므로 배열 객체의 생성 부분을 생략할 수 있습니다.

② 배열에서 배열의 요소 하나씩을 자동으로 꺼내주면서 반복이 실행됩니다. 꺼내진 배열의 요소는 int e 변수에 대입됩니다.

 

for ~ each문에는 기본 자료형뿐 아니라 객체 자료형을 가진 배열도 사용할 수 있습니다. 예제를 통해 살펴보겠습니다.

 

class House
{
    private int houseNum;
    private String name;
    
    House(int houseNum, String name)
    {
        this.houseNum = houseNum;
        this.name = name;
    }
    
    public int getHouseNum()
    {
        return houseNum;
    }
    
    public String getName()
    {
        return name;
    }
}

public class Ex09_EnhancedForObject
{
    public static void main(String[] args)
    {
        House[] arr = new House[5];      // ①
        
        arr[0] = new House(101, "홍길동"); // ②
        arr[1] = new House(102, "전우치");
        arr[2] = new House(103, "손오공");
        arr[3] = new House(104, "해리포터");
        arr[4] = new House(105, "멀린");
        
        for(House e: arr) // ③ 향상된 기능의 for문
        {
            if(e.getHouseNum() == 102) // ④
                System.out.println(e.getName()); // ⑤
        }
    }       
}

 

▼ 실행 결과

 

먼저 House 클래스를 정의합니다. 멤버 변수로 방번호를 저장할 houseNum과 이름을 저장할 name 변수를 가지고 있습니다. 변수가 다 private으로 은닉화되어 있기 때문에 생성자를 통해 값을 세팅하고 게터를 통해서 값을 참조합니다.

① 배열을 선언합니다.

② 객체를 생성하고 배열의 개별 요소에 참조 값을 대입합니다.

③ 향상된 기능의 for문을 통해 모든 요소를 하나씩 꺼내서 참조합니다. ④, ⑤에서 게터 메서드로 객체의 멤버 변수의 값을 꺼내서 값을 비교하고 출력합니다.

 

4. 배열과 차원

배열은 2차원 배열, 3차원 배열과 같이 다차원 배열을 사용할 때도 많습니다. 하지만 컴퓨터 메모리의 구조는 1차원이므로 2차원, 3차원 배열도 실제로는 1차원 공간에 저장합니다. 다시 말해 배열은 차원과는 무관하게 메모리에 연속 할당됩니다. 현실에서는 1차원, 2차원 배열을 주로 사용하고, 3차원 배열마저도 아주 가끔 사용합니다.

 

4.1 2차원 배열

2차원 배열은 1차원 배열을 확장한 겁니다.

 

int[][] arr = {{1, 2, 3}, {4, 5 ,6}}; // 2행 3열 2차원 배열 선언

 

이를 그림으로 나타내면 다음과 같습니다.

 

 

왼쪽은 2차원 배열을 사람이 이해하기 쉽도록 2차원으로 표현한 것이고, 오른쪽은 실제 메모리에 2차원 배열이 저장된 상태를 표현한 겁니다. 사람이 이해하기에는 왼쪽의 형태로 이해하는 것이 편리하므로 2차원 배열을 왼쪽의 행과 열 공간처럼 표현하는 경우가 많지만 실제로는 오른쪽처럼 0행, 1행 순서로 데이터를 할당해 1차원 공간에 저장합니다. 이런 배열의 특성을 잘 기억해두기 바랍니다.

지금까지 사용한 1차원 배열은 다음과 같았습니다.

 

int [ ] arr1 = new int [3];

 

 

그냥 0호라고 말하면 어느 집의 0호인지 알 수 없어 한아름빌라 0호, 한아름빌라 1호 이런 식으로 얘기한다고 했습니다. 이제 여러 층이 있어 지하 1호는 0-1호, 지하 2호는 0-2호, 지하 3호는 0-3호, 1층의 1호는 1-1호, 1층의 2호는 1-2호 등 앞 쪽의 숫자로 층을 구분할 수 있습니다.

배열도 이런 식입니다. 배열에서도 앞쪽을 층으로 생각하고 뒤를 방으로 생각하면 됩니다. 선언은 다음과 같이 합니다.

 

int[][] arr2 = new int[3][3];

 

 

2차원 배열 요소 전체의 순차적 접근은 중첩된 반복문을 이용하면 쉽게 접근할 수 있습니다. 코드로 작성하면 다음과 같이 됩니다.

 

public class Ex10_ForInFor
{
    public static void main(String[] args)
    {
        int[][] arr = new int[3][3]; // ①
        
        int num = 1;
        
        for(int i=0; i<3; i++) {
            // 먼저 i로 층을 정하고 여기서 j로 각 층의 방을 다 돕니다.
            for(int j=0; j<3; j++) { // ②
                arr[i][j] = num;     // ③
                num++;               // ④
            }
        }
        
        for(int i=0; i<3; i++) {
            for(int j=0; j<3; j++) {
                System.out.print(arr[i][j] + "\t"); // ⑤
            }
            System.out.println();
        }
    }
}

 

▼ 실행 결과

 

① 2차원 배열을 선언합니다.

② 바깥쪽 for문의 i의 값 한 개당 내부의 for문이 한 바퀴씩 돕니다. ③ 각 배열 요소에 num 변수의 값을 대입합니다. ④ num 변수의 값을 하나씩 증가시킵니다.

⑤ 중첩된 for문을 통해 2차원 배열의 모든 요소의 값을 가져와서 출력합니다.

 

4.2 2차원 배열의 실제 구조

int[][] arr3 = new int[3][4];

 

위 코드는 다음처럼 세 배열이 각각 길이가 4개인 배열을 가지고 있는 구조입니다.

 

 

더 구체적으로 그리면 다음과 같게 됩니다.

 

 

이런 구조이기 때문에 자바에서는 다음과 같은 초기화가 가능합니다.

 

 

public class Ex11_PartiallyFilled
{
    public static void main(String[] args)
    {
        int[][] arr = {
                {11},
                {22, 33},
                {44, 55, 66}
            };
    
        // 배열의 구조대로 내용 출력
        for(int i=0; i<arr.length; i++) // ②
        {
            for(int j=0; j<arr[i].length; j++) // ③
            {
                System.out.print(arr[i][j] + "\t"); // ④
            }
            System.out.println();
        }
    }
}

 

▼ 실행 결과

 

① 부분적으로 채워진 2차원 배열을 만들고 초기화합니다.

② 바깥쪽 배열의 크기를 이용해 반복문을 반복합니다. ③ 바깥쪽 배열의 요소 하나당 배열의 크기를 구해서 반복문을 반복합니다. ④ 배열의 개별 요소의 값을 구해와서 출력합니다.

 

5. 배열 관련 유틸리티 메서드

여기서는 배열을 편하게 사용하게 해주는 여러 메서드를 알아보겠습니다.

 

5.1 배열의 초기화 메서드

앞에서도 배열을 선언할 때 초기화 값을 이용하여 초기화를 했습니다. 그러나 배열이 엄청 클 때는 값을 직접 일일이 지정해주는 초기화 방식은 무리입니다. 그래서 배열의 초기화는 다음의 메서드를 이용하게 됩니다.

다음 클래스에 있는 메서드를 사용하여 원하는 값으로 배열 전부 또는 일부를 채울 수 있습니다.

 

▼ java.util.Arrays 클래스에 정의되어 있는 메서드

public static void fill(int[] a, int val)
// 두 번째 매개변수로 전달된 값으로 배열 초기화

public static void fill(int[] a, int fromIndex, int toIndex, int val)
// 인덱스 fromIndex ~ (toIndex-1) 범위까지 val값으로 배열 초기화

 

5.2 배열의 복사 Array 클래스

배열 복사는 다음의 두 클래스에 있는 메서드를 사용할 수 있습니다.

 

▼ java.util.Arrays 클래스에 정의되어 있는 메서드

public static int[] copyOf(int[] original, int newLength)
// original에 전달된 배열을 첫 번째 요소부터 newLength 길이만큼 복사

public static int[] copyOfRange(int[] original, int from, int to)
// original에 전달된 배열을 인덱스 from부터 to 이전 요소까지 복사

 

▼ java.util.System 클래스에 정의되어 있는 메서드


public static void arraycopy(Object src, int srcPos, Object dest, int destPos,
int length)
// 배열 src의 srcPos에서 배열 dest의 destPos로 length 길이만큼 복사


import java.util.Arrays; // ①

public class Ex12_ArrayCopy
{
    public static void main(String[] args)
    {
        int[] arr1 = new int[10]; // ②
        int[] arr2 = new int[8];  // ③
        
        // 배열 arr1을 3으로 초기화
        Arrays.fill(arr1, 3); // ④
        
        // 배열 arr1을 arr2로 부분 복사
        System.arraycopy(arr1, 0, arr2, 3, 4); // ⑤
        
        // arr1 출력
        for(int i=0; i<arr1.length; i++)
            System.out.print(arr1[i] + " ");
        System.out.println();
        
        // arr2 출력
        for(int i=0; i<arr2.length; i++)
            System.out.print(arr2[i] + " ");
        System.out.println();
        
        // 배열 arr1을 arr3로 부분 복사
        int[] arr3 = Arrays.copyOfRange(arr2, 2, 5); // ⑥
        
        // arr3 출력
        for(int i=0; i<arr3.length; i++)
            System.out.print(arr3[i] + " ");
        System.out.println();
    }
}

 

▼ 실행 결과

 

① java.util.Arrays 클래스를 임포트합니다.

② 길이가 10인 arr1 배열은 0으로 초기화됩니다. ③ 길이가 8인 arr2 배열은 0으로 초기화됩니다.

④ Arrays 클래스의 스태틱 메서드인 fill() 메서드를 이용하여 지정한 값으로 배열을 채워줄 수 있습니다.

⑤ System 클래스의 스태틱 메서드인 arraycopy() 메서드를 이용하여 기존에 만들어진 배열에 부분 복사를 할 수 있습니다.

⑥ Arrays 클래스의 스태틱 메서드인 copyOfRange() 메서드가 배열에서 부분 복사하여 반환한 객체를 배열에 대입할 수 있습니다.

System.arraycopy()는 기존에 만들어진 배열에 복사한 값을 넣어주는 것이고, Arrays.copyOfRange()는 배열에서 부분 복사한 값을 이용하여 배열 객체를 만들어 반환하고 배열 변수에 대입을 해주는 차이점이 있습니다.

 

5.3 배열 내용 비교

Arrays 클래스에는 배열을 비교해주는 equals() 메서드가 있습니다. 두 배열에 저장된 데이터의 수, 순서 그리고 내용이 같을 때 true를 반환합니다(배열 길이가 다르면 false를 반환합니다).

 

import java.util.Arrays; // ①

public class Ex13_ArrayEquals
{
    public static void main(String[] args)
    {
        int[] arr1 = {1, 2, 3, 4, 5}; // ②
        int[] arr2 = Arrays.copyOf(arr1, arr1.length); // ③
        
        boolean bCheck = Arrays.equals(arr1, arr2);    // ④
        System.out.println(bCheck);
    }
}

 

▼ 실행 결과

 

① java.util.Arrays 클래스를 임포트합니다.

② 배열을 선언하고 값을 직접 대입하여 초기화해줍니다. ③ Arrays 클래스의 copyOf() 메서드를 이용하여 배열을 복사합니다. ④ 두 배열의 내용을 비교합니다.

 

5.4 배열의 내용 정렬

Arrays 클래스에는 배열을 내용을 정렬해주는 sort() 메서드가 있습니다.

 


public static void sort(int[] a)
// 매개변수 a로 전달된 배열을 오름차순으로 정렬


import java.util.Arrays;

public class Ex14_ArraySort
{
    public static void main(String[] args)
    {
        int[] arr1 = {1, 3, 2, 4};
        double[] arr2 = {4.4, 3.3, 2.2, 1.1};
        String[] arr3 = {"홍길동", "전우치", "손오공", "멀린"};
        
        Arrays.sort(arr1); // 2
        Arrays.sort(arr2);
        Arrays.sort(arr3);
        
        for (int n : arr1) // 2
            System.out.print(n + "\t");
        System.out.println();
        
        for (double d : arr2)
            System.out.print(d + "\t");
        System.out.println();
        
        for (String s : arr3)
            System.out.print(s + "\t");
        System.out.println();
    }
}

 

▼ 실행 결과

 

① 기존 배열 안의 값을 정렬해줍니다. ② 향상된 기능의 for문을 이용하여 배열 안의 내용을 하나씩 꺼내서 변수 n에 대입합니다.

 

6. ArrayList 사용법

ArrayList는 배열은 아니지만 배열 기반이라 자바에서 크기가 동적으로 변경되는 배열이 필요할 때 활용합니다. 여기서는 ArrayList에 데이터를 삽입하는 방법을 알아보겠습니다.

 

6.1 add( ) 메서드로 데이터 추가

맨 끝에 데이터를 추가하려면 add( ) 메서드를 사용하면 됩니다.

 

ArrayList<Integer> list = new ArrayList<>();
// 리스트의 맨 끝에 데이터 추가
list.add(1); // [1]
list.add(2); // [1, 2]
list.add(3); // [1, 2, 3]

 

6.2 다른 컬렉션의 데이터로부터 초기화

ArrayList의 생성자의 매개변수로 컬렉션을 넘기면 매개변수로 넘긴 컬렉션에 담긴 데이터로 초기화할 수 있습니다.

 

ArrayList<Integer> list = new ArrayList<>();
// 리스트의 맨 끝에 데이터 추가
list.add(1); // [1]
list.add(2); // [1, 2]
list.add(3); // [1, 2, 3]

ArrayList<Integer> list2 = new ArrayList<>(list);
System.out.println(list2); // [1, 2, 3]

 

6.3 get( ) 메서드로 인덱스를 통해 데이터에 접근

특정 인덱스에 있는 데이터에 접근하기 위해서는 get( ) 메서드를 사용하면 됩니다.

 

ArrayList<Integer> list = new ArrayList<>();
// 리스트의 맨 끝에 데이터 추가
list.add(1); // [1]
list.add(2); // [1, 2]
list.add(3); // [1, 2, 3]

System.out.println(list.get(1)); // 2

 

6.4 remove( ) 메서드로 데이터 삭제

remove( ) 메서드를 사용하면 특정 위치의 데이터를 삭제할 수 있습니다.

 

ArrayList<Integer> list = new ArrayList<>();
// 리스트의 맨 끝에 데이터 추가
list.add(1); // [1]
list.add(2); // [1, 2]
list.add(3); // [1, 2, 3]

list.remove(list.size() - 1); // 끝에 있는 데이터 삭제
System.out.println(list); // [1, 2]

 

7. 깨알 같은 배열, ArrayList 연관 메서드

활용하면 유용한 깨알 같은 몇 가지 기능을 코드와 함께 소개하겠습니다.

  • 배열의 전체 데이터 개수를 가진 length 변수
  • 배열의 모든 데이터를 정렬하는 Arrays 클래스의 sort( ) 메서드
  • 배열의 모든 데이터를 String으로 반환하는 Arrays 클래스의 toString( ) 메서드
  • ArrayList의 전체 데이터 개수를 반환하는 size( ) 메서드
  • ArrayList에 저장된 데이터가 없는지 여부를 반환하는 isEmpty( ) 메서드
  • ArrayList의 모든 데이터를 정렬하는 Collections 클래스의 sort( ) 메서드

int[] arr = {1, 2, 4, 5, 3};
System.out.println(arr.length); // 5
Arrays.sort(arr); // 정렬 [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(arr)); // 출력 [1, 2, 3, 4, 5]

ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 4, 5, 3));
System.out.println(list.size()); // 5
System.out.println(list.isEmpty()); // false
Collections.sort(list); // 정렬 [1, 2, 3, 4, 5]
System.out.println(list); // 출력 [1, 2, 3, 4, 5]

 

sort( ) 메서드에 정렬하려는 대상 외에 다른 인수를 전달하지 않으면 전체 데이터를 오름차순으로 정렬합니다. 특정 범위의 데이터만 정렬하고자 할 때에는 From 인덱스와 To 인덱스를 지정해서 정렬할 수도 있습니다.

저자 김희성

현 42dot 백엔드 개발자. 이전에는 삼성SDS에서 소프트웨어 개발자, 쿠팡에서 풀스택 개발자로 근무했다. 특히 삼성SDS 시절에는 사내 SW역량테스트 강사로 활약했다. 귀찮은 거 싫어하고 집에서 자는 게 가장 좋은 백엔드 개발자다. 어려운 문제와 맞닥뜨렸을 때 더욱 불타오르는 타입. 새벽 시간에 코드짜는 걸 좋아하며 주말에 밤새 코딩하는 일을 즐기는 ESTJ.

저자 이재환

27년차 개발자로 최근 12여 년간 여러 교육 기관에서 자바와 모바일 앱 개발, 빅데이터 강의를 겸하고 있습니다. 인프런에서 〈예제로 배우는 스프링 부트 입문〉, 〈디자인 패턴 with JAVA(GoF)〉, 〈자바 : 클래스의 이해와 객체지향 프로그래밍〉 등의 온라인 강의도 진행합니다. 저서로는 《예제로 배우는 스프링 부트 입문》(비제이퍼블릭, 2020), 《핵심강좌! 유니티》(유페이퍼, 2018), 《핵심강좌! Cocos2d-X》(유페이퍼, 2017)가 있습니다.

Leave a Reply

©2020 GoldenRabbit. All rights reserved.
상호명 : 골든래빗 주식회사
(04051) 서울특별시 마포구 양화로 186, 5층 512호, 514호 (동교동, LC타워)
TEL : 0505-398-0505 / FAX : 0505-537-0505
대표이사 : 최현우
사업자등록번호 : 475-87-01581
통신판매업신고 : 2023-서울마포-2391호
master@goldenrabbit.co.kr
개인정보처리방침
배송/반품/환불/교환 안내