프로그래밍 공부
[자바] #06. 배열의 정렬 sort 본문
배열의 정렬에 사용되는 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()를 사용하면 내림차순 정렬이 가능하다.
'자바' 카테고리의 다른 글
| [자바] #08. 와일드카드 (Wildcard) - 1. 제네릭 <T>와 와일드카드 (?) (0) | 2025.02.15 |
|---|---|
| [자바] #07. 제네릭 (Generics) (0) | 2025.02.15 |
| [자바] #05. Object 클래스에 정의되어 있는 주요 메소드 (equals, clone) (0) | 2025.02.14 |
| [자바] #04. 자바에서의 메모리 구조 - 메소드 영역과 힙 영역 (0) | 2025.02.14 |
| [자바] #03. 예외 클래스의 구분, try-with-resources 구문 (0) | 2025.02.14 |