본문 바로가기
Backend/알고리즘

자료구조 - 배열

by 박상윤 2024. 2. 23.

배열이란?

하나의 블록안에 여러 데이터들을 모아 저장함으로써 데이터를 구조적으로 다루는데 도와준다.

배열의 각 구성요소를 배열 요소(element)라고 하며, 배열에서 위치를 가리키는 숫자를 인덱스(index)라고 한다.

int arr[] = new int[5];
// 0 0 0 0 0
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 1 2 3 4 5 6 7 8 9 10

 

배열 선언

배열은 선언시 미리 공간의 갯수(길이)를 지정해야 한다.

공간의 갯수 제한이 생긴므로 데이터를 저장하는데 있어서 제한적인 상황이 생길 수 있다.

// 일일히 하나씩 초기화
int[] arr = new int[5];
arr[0] = 1; // 인덱스로 값 초기화
arr[1] = 1;
arr[2] = 1;
arr[3] = 1;
arr[4] = 1;

// 반복문 초기화
for(int i = 0; i < score.length; i++){
	arr[i] = i+1;
}


// 선언 초기화
int[] arr = {1,2,3,4,5};

 

배열 출력

int[] arr = {1,2,3,4,5};
System.out.println(arr); // [I@7ad041f3] -> 주솟값이 출력된다.

 

콘솔에 배열을 System.out.println()으로 출력하면 배열 내부가 아닌 주솟값이 출력된다.

배열을 출력하기 위해서는 for문을 사용해서 배열 각 원소들을 순회해서 출력해주거나, 자바에서 제공하는 Arrays.toString() 메소드를 사용해서 배열을 문자열 형식으로 만들어 출력해줄 수 있다.

 

배열 복사

공간의 제약이 있는 배열을 확장시켜주려면 어떻게 해야하는가?

공간이 큰 배열을 새로 만들고 기존의 배열의 내용을 새로 만든 배열에 복사하는 방식으로 확장시켜야 한다.

 

배열을 복사하는 방법은 for문으로 순회해서 직접 한 요소요소 복사하는 방식과, 자바에서 제공하는 System.arraycopy() 메서드나 Arrays.copyOf() 메서드를 사용해주면 된다.

public static void main(String[] args){
	int[] arr1 = {1,2,3,4,5};
    int[] arr2 = new int[arr1.length * 2];
    
    arr2 = Arrays.copyOf(arr1, arr1.length); // arr1 배열을 arr1.length 전체 길이만큼 전체 복사
    System.out.println(Arrays.toString(arr2)); // [1,2,3,4,5]
}

 

배열 정렬

Arrays.sort()메서드를 사용해서 배열을 정렬할 수 있다.

 

배열 비교

두 배열의 구성이 같은지에대한 여부를 확인하기 위해서 일일히 for문으로 순회하여 원소를 비교해도 되지만,

Arrays.equals() 메소드를 이용하면 된다.

public static void main(String[] args){
	
    String[] arr1 = {"가", "나", "다", "라"};
    String[] arr2 = {"가", "나", "다", "라"};
    
    System.out.println("arr1 == arr2 : " + Arrays.equals(arr1,arr2));
    // arr1 == arr : true
}

 

 

다차원 배열

2차원 이상의 배열을 의미하며, 배열 요소로 또 다른 배열을 가지는 배열을 의미한다.

 

2차원 배열 생성

int[][] score = new int[2][2];

// 선언후 데이터 삽입
score[0][0] = 1;
score[0][1] = 2;
score[1][0] = 3;
score[1][1] = 4;

// 한번에 지정해서 선언
int[][] score2 = {
	{1,2},
    {3,4}
}

 

 

2차원 배열 출력

중첩 for문을 사용하거나, Java에서 제공하는 Arrays.deepToString() 메서드를 통해 2차원 배열을 한방에 출력한다.

int[][] arr = {
	{1,2,3},
    {4,5,6},
    {7,8,9}
}

System.out.println(Arrays.deepToString(arr)); // [[1,2,3],[4,5,6],[7,8,9]]

 

2차원 배열 비교

2차원 배열은 Arrays.deepToEquals()메소드를 사용하면 된다.

 

 

가변 배열

Java에서 다차원 배열은 마지막 차수의 길이를 다르게 지정할 수 있다.

int[][] score = {
	{1,2,3,4,5},
    {2,3,4},
    {6,5}
}

 

객체 배열

배열에 정수나 문자외에 객체 자체도 배열에 넣어줄 수 있다.

객체 또한 하나의 자료형으로 취급된다.

class ObjectMake {
	int id;
    String descritpion;
    
    Object(int id, String description){
    	this.id = id;
        this.description = description;
    }
    


ObjectMake[] arrayObjMake = new ObjectMake[5];

arrayObjMake[0] = new ObjectMake(1,"hi");
arrayObjMake[1] = new ObjectMake(2,"bye");
arrayObjMake[2] = new ObjectMake(3,"good night");

System.out.println(arrayObjMake[0].description); // "hi"

// 초기화 선언
ObjectMake[] arrayObjMake2 = {
	new ObjectMake(1,"hi");
	new ObjectMake(2,"bye");
	new ObjectMake(3,"good night");
};

 

 

객체 배열 복사

객체로 이루어진 배열을 복사할 때 주의해야 할 점이 있다.

배열 자체는 복사가 되지만, 배열 내용물 객체는 참조 복사(주소 복사)가 된다.

 

배열 내용물은 여전히 같은 객체 주소를 가리키기 때문에 객체도 복사 되는 줄 알고 복사한 객체의 멤버를 변경시에 복사된 멤버에게 즉 참조하고 있는 멤버의 객체도 변경이 된다.

 

깊은 복사를 위해서는 for문으로 일일히 복사해주어야 한다.

class myObject{
    int id;
    String description;

    myObject(int id, String description) {
        this.id = id;
        this.description = description;
    }
}

myObject[] arrayObj = {
    new myObject(101, "first"), 
    new myObject(102, "second"), 
    new myObject(103, "third")
};
System.out.println(Arrays.toString(arrayObj)); // [main$1myObject@251a69d7, main$1myObject@7344699f, main$1myObject@6b95977]

myObject[] arrayObj2 = new myObject[3];
for(int i = 0; i < arrayObj.length; i++) {
    arrayObj2[i] = new myObject(arrayObj[i].id, arrayObj[i].description);
}

// 배열 내용물 객체의 @주소가 달라짐을 볼 수 있다.
System.out.println(Arrays.toString(arrayObj2)); // [main$1myObject@7e9e5f8a, main$1myObject@8bcc55f, main$1myObject@58644d46]

System.out.println(arrayObj[0].id); // 101
arrayObj2[0].id = 999; // 복사한 arrayObj2의 첫째 객체의 멤버를 변경
System.out.println(arrayObj2[0].id); // 999
System.out.println(arrayObj[0].id); // 101

 

 

객체 배열 정렬

객체 배열을 정렬할 때는 정렬의 기준이 필요하다.

객체 배열을 정렬하기 위해서는 Comparable 인터페이스와 Comparator 클래스를 이용한 방법을 통해 객체 배열 정렬을 할 수 있다.

 

Comparable

같은 타입의 인스턴스를 서로 비교해야 할때 Comparable 인터페이스를 구현해서 compareTo() 메소드를 오버라이딩 정의하고 사용한다.

import java.util.Arrays;

public class main {
    public static void main(String[] args) {
		
        // 클래스에 Comparable<> 인터페이스를 구현한다
        class User implements Comparable<User> { 
            String name;
            int age;

            User(String name, int age) {
                this.name = name;
                this.age = age;
            }

            @Override
            public int compareTo(User user) {
                // 비교 로직을 구현
                if (this.age < user.age) {
                    return -1;
                } else if (this.age == user.age) {
                    return 0;
                } else {
                    return 1;
                }
            }
        }

        User[] users = {
            new User("홍길동", 32),
            new User("김춘추", 64),
            new User("임꺽정", 48),
            new User("박혁거세", 14),
        };

        Arrays.sort(users); // 나이순 정렬
        // Arrays.sort(users, Collections.reverseOrder()); // 역순 정렬
        
        for (User u : users) { // 출력
            System.out.println(u.name + " " + u.age + "세");
        }
    }
}

 

Comparator 클래스

Comparator 클래스도 Comparable 인터페이스와 같이 객체를 정렬하는 데 사용된다.

import java.util.Arrays;
import java.util.Comparator; // Comparator 클래스를 불러온다

public class main {
    public static void main(String[] args) {

        class User {
            String name;
            int age;

            User(String name, int age) {
                this.name = name;
                this.age = age;
            }
        }

        User[] users = {
            new User("홍길동", 32),
            new User("김춘추", 64),
            new User("임꺽정", 48),
            new User("박혁거세", 14),
        };

		// Arrays.sort(배열, new Comparator<>() { ... });
        Arrays.sort(users, new Comparator<User>() {
            @Override
            public int compare(User u1, User u2) {
                return Integer.compare(u1.age, u2.age); // Integer 클래스에 정의된 compare 함수로 두 가격 정수 원시값을 비교
            }
        });

        // java8 람다식으로 다음과 같이 축약이 가능
        Arrays.sort(users, (u1, u2) -> Integer.compare(u1.age, u2.age)); // 나이순 정렬
        
        // 출력
        for (User u : users) { 
            System.out.println(u.name + " " + u.age + "세");
        }

    }
}

 

나이순이 아닌 이름(문자열) 순으로 정렬하려면 compareTo() 메서드를 사용하면 된다.

 

 

'Backend > 알고리즘' 카테고리의 다른 글

자료구조 - Linked List  (2) 2024.02.24
자료구조 - HashMap  (1) 2024.02.24
[백준] 2343번 - 기타레슨  (1) 2023.12.08
[백준] 2729번 - 보석상자  (0) 2023.12.08
이분탐색  (1) 2023.12.07