Notice
Recent Posts
Recent Comments
Link
«   2026/03   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags more
Archives
Today
Total
관리 메뉴

프로그래밍 공부

[자바] #06. 배열의 정렬 sort 본문

자바

[자바] #06. 배열의 정렬 sort

하 냥 2025. 2. 15. 03:13

배열의 정렬에 사용되는 Arrays의 메서드는 public static void sort(int[] a) 이다.

이 메서드는 기본형(primitive type)과 객체(object) 배열 모두 정렬할 수 있다.

또한 정렬 방식을 오름차순 또는 내림차순(커스텀 Comparator 사용)으로 설정할 수도 있다.

 

📢Arrays.sort() 의 기본 동작

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] numbers = {5, 2, 9, 1, 6};

        Arrays.sort(numbers);  // 오름차순 정렬
        System.out.println(Arrays.toString(numbers)); // [1, 2, 5, 6, 9]
    }
}

기본적으로 Arrays.sort()는 오름차순 정렬을 수행한다.

 문자열은 알파벳순(사전순)으로 정렬된다.

 

📢 Arrays.sort()의 정렬 알고리즘

기본형 배열(Primitive Type): Dual-Pivot QuickSort를 사용

  • 평균 시간 복잡도: O(N log N)

객체 배열(Object Type): TimSort (병합 정렬 + 삽입 정렬 기반)

  • 평균 시간 복잡도: O(N log N)
  • 객체의 비교 기준(Comparator)을 설정할 수 있다.

 

📢 객체 배열 정렬 (Comparable 인터페이스 사용)

사용자 정의 객체를 정렬하려면 Comparable 인터페이스를 구현해야 한다.

import java.util.Arrays;

class Student implements Comparable<Student> {
    String name;
    int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    @Override
    public int compareTo(Student other) {
        return this.score - other.score; // 점수 기준 오름차순 정렬
    }
    @Override
    public String toString() {
        return name + "(" + score + ")";
    }
}

public class Main {
    public static void main(String[] args) {
        Student[] students = {
            new Student("Alice", 85),
            new Student("Bob", 92),
            new Student("Charlie", 78)
        };

        Arrays.sort(students);  // compareTo() 기준으로 정렬
        System.out.println(Arrays.toString(students)); // [Charlie(78), Alice(85), Bob(92)]
    }
}

 compareTo() 메서드를 구현하면, Arrays.sort()가 자동으로 해당 기준에 따라 정렬한다.

 참고로 int CompareTo(Object o) 메소드는

    호출하는 인스턴스가 작다면(= 인자로 전달된 o가 크다면) 음의 정수를 반환,

    호출하는 인스턴스가 크다면(= 인자로 전달된 o가 작다면) 양의 정수를 반환,

    같다면 0을 반환한다.

    따라서 other.age - this.age 은 내림차순 정렬이 된다.

 


❓ 여기서 소소한 질문. 왜 compareTo() 메서드는 인자로 Student 객체를 바로 받을 수 있는가?

     eqauls() 메서드는 인자로 Object o를 받게끔 오버라이딩 했어야 했는데...

❕ 그 이유는 Comparable<T> 인터페이스가 제네릭이기 때문이다!

 

이를 이해하기 위해 제네릭이 없는 초기의 Comparable을 사용해 보자.

class Student implements Comparable {
    String name;
    int score;
    
    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    @Override
    public int compareTo(Object o) {  // Object 타입을 받음 (문제 발생 가능)
        Student other = (Student)o;  // 다운캐스팅 필요 (비효율적)
        return this.score - other.score;
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("Alice", 85);
        Student s2 = new Student("Bob", 92);
        
        System.out.println(s1.compareTo(s2)); // 정상 동작
        System.out.println(s1.compareTo("잘못된 타입!")); // 🚨 런타임 오류 발생!
    }
}

compareTo()가 Object 타입을 받기 때문에 잘못된 타입(String)을 넘겨도 컴파일 에러 없이 실행되지만, 런타임 오류 발생!

타입 안정성이 낮아서 안전하지 않다.

 

그럼 밑의 제네릭을 사용한 Comparable<T>를 보자.

Comparable<T> 인터페이스는 타입을 명확히 지정할 수 있도록 개선되었다.

public interface Comparable<T> {
    int compareTo(T o);
}

T는 비교할 대상의 타입을 의미하며, Object가 아니라 특정 타입만 허용할 수 있다.

즉, compareTo(Student o)로 해도 Comparable<Student>를 구현하면 문제없이 동작하는 것이다.

compareTo(Student o)로 선언해도 문제 없이 오버라이딩할 수 있는 이유가 바로 Comparable<T>가 제네릭이기 때문.


 

 

📢 Comparator를 활용한 커스텀 정렬

특정 조건에 따른 정렬을 원한다면 Comparator를 사용해야 한다.

import java.util.Arrays;
import java.util.Comparator;

class Student {
    String name;
    int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
    @Override
    public String toString() {
        return name + "(" + score + ")";
    }
}

public class Main {
    public static void main(String[] args) {
        Student[] students = {
            new Student("Alice", 85),
            new Student("Bob", 92),
            new Student("Charlie", 78)
        };

        // 점수 기준 내림차순 정렬
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return s2.score - s1.score; // 내림차순 정렬
            }
        });

        System.out.println(Arrays.toString(students)); // [Bob(92), Alice(85), Charlie(78)]
    }
}

 

 

📢 List.sort()를 사용한 정렬 Collections.sort()

배열이 아니라 리스트(List)를 정렬할 때는 Collections.sort()를 사용할 수 있다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(List.of(5, 2, 9, 1, 6));

        Collections.sort(numbers);  // 오름차순 정렬
        System.out.println(numbers); // [1, 2, 5, 6, 9]

        Collections.sort(numbers, Collections.reverseOrder());  // 내림차순 정렬
        System.out.println(numbers); // [9, 6, 5, 2, 1]
    }
}

Collections.sort()는 List<T> 타입의 데이터를 정렬할 때 사용한다.

Collections.reverseOrder()를 사용하면 내림차순 정렬이 가능하다.