Home [Java] 기본 정렬 메소드와 객체 정렬
Post
Cancel

[Java] 기본 정렬 메소드와 객체 정렬

Arrays.sort, Collections.sort, 커스텀 Comparator, 객체 정렬까지 정렬의 모든 것을 정리했습니다.

1️⃣ 기본 정렬

🔹 1-1. 기본 배열 정렬 (Arrays.sort)

  • 기본형 배열은 Dual-Pivot Quicksort 사용 (평균 O(N log N))
  • 참조형 배열은 TimSort 사용 (O(N log N))
1
2
3
int[] arr = {5, 1, 4, 2, 3};
Arrays.sort(arr); // 오름차순
System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 5]

🔹 1-2. 리스트 정렬 (Collections.sort)

  • 내부적으로 List를 배열로 변환 후 TimSort 적용
  • 오름차순은 자연 순서(Natural Order)로 동작
1
2
3
List<Integer> list = Arrays.asList(5, 1, 4, 2, 3);
Collections.sort(list); // 오름차순
System.out.println(list); // [1, 2, 3, 4, 5]

2️⃣ 내림차순 정렬

🔹 2-1. 배열 내림차순 (Integer[] 사용)

  • 원시 자료형 불가능, 객체 자료형으로 선언 필수
  • int[] 는 불가능 → Integer[]로 박싱해야 함
1
2
3
Integer[] arr = {5, 1, 4, 2, 3};
Arrays.sort(arr, Collections.reverseOrder());
System.out.println(Arrays.toString(arr)); // [5, 4, 3, 2, 1]

🔹 2-2. 리스트 내림차순

1
2
3
4
List<Integer> list = Arrays.asList(5, 1, 4, 2, 3);
list.sort(Collections.reverseOrder()); 
// Collections.sort(list, Collections.reverseOrder()) 도 가능
System.out.println(list); // [5, 4, 3, 2, 1]

3️⃣ 커스텀 정렬 (Comparator 사용)

🔹 3-1. 람다로 바로 정의

  • 문자열 길이 기준 오름차순 정렬
  • a - b 대신 Integer.compare(a, b) 권장 (오버플로 방지)
1
2
3
String[] arr = {"apple", "banana", "kiwi", "grape"};
Arrays.sort(arr, (a, b) -> Integer.compare(a.length(), b.length())); 
System.out.println(Arrays.toString(arr)); // [kiwi, apple, grape, banana]

🔹 3-2. Collections.sort()에 바로 Comparator

1
2
3
4
5
6
7
8
9
10
List<String> list = Arrays.asList("apple", "banana", "kiwi", "grape");
Collections.sort(list, (a, b) -> b.compareTo(a)); // 내림차순
System.out.println(list); // [kiwi, grape, banana, apple]

Collections.sort(list, new Comparator<String>() {
  	 @Override
     public int compare(String o1, String o2) {
         return o1.length() - o2.length();
     }
});

4️⃣ 객체에서 정렬

🔹 4-1. Comparable 인터페이스 구현

  • Comparable은 클래스 내부에서 기본 정렬 기준 정의
  • Arrays.sort() / Collections.sort() 호출 시 자동 적용
  • 예시: 사람(Person)을 나이(age) 오름차순 정렬
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
32
33
34
35
36
37
38
39
40
41
42
class Person implements Comparable<Person> {
    String name;
    int age;

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

    // Comparable 인터페이스 구현
    @Override
    public int compareTo(Person o) {
        return Integer.compare(this.age, o.age); // 나이 오름차순
        // return this.age - other.age; // 오름차순
        // return o.age - this.age; // 내림차순
    }

    @Override
    public String toString() {
        return name + " (" + age + ")";
    }
}

public class Main {
    public static void main(String[] args) {
        Person[] arr = {
            new Person("Kim", 30),
            new Person("Lee", 20),
            new Person("Park", 25)
        };
        Arrays.sort(arr);

        List<Person> list = new ArrayList<>();
        list.add(new Person("Alice", 30));
        list.add(new Person("Bob", 20));
        list.add(new Person("Charlie", 25));
        Collections.sort(list);

        System.out.println(Arrays.toString(arr)); 
        // [Lee (20), Park (25), Kim (30)]
    }
}

🔹 4-2. Comparator로 외부에서 정렬 정의

  • 정렬 시 Comparator를 익명 클래스/람다로 직접 전달
  • 정렬 기준을 외부에서 유연하게 정의
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Arrays.sort(arr, new Comparator<Person>() {
    @Override
    public int compare(Person p1, Person p2) {
        return p2.name.compareTo(p1.name); // 이름 내림차순
    }
});

Comparator<Person> comparator = new Comparator<Person>() {  // 객체 정의
    @Override
    public int compare(Person a, Person b) {
        return b.age - a.age; // 나이 내림차순
    }
};
Collections.sort(list, comparator);

// 람다 이용
Arrays.sort(arr, (p1, p2) -> p1.name.compareTo(p2.name)); // 이름 오름차순

Collections.sort(list, (a, b) -> b.age - a.age);  // 나이 내림차순
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Main {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("Alice", 30));
        list.add(new Person("Bob", 20));
        list.add(new Person("Charlie", 25));

        // 1) 나이 오름차순
        list.sort(new Comparator<Person>() {
            @Override
            public int compare(Person a, Person b) {
                return a.age - b.age;
            }
        });

        // 2) 또는 람다 사용 (Java 8+)
        list.sort((a, b) -> a.age - b.age);

        // 3) 이름 기준 내림차순
        list.sort((a, b) -> b.name.compareTo(a.name));

        System.out.println(list);
    }
}

🔹 4-3. 다중 조건 정렬 (예: 나이 오름차순, 같으면 이름 사전순)

1
2
3
4
5
6
7
8
9
10
11
12
13
Arrays.sort(arr, (p1, p2) -> {
    if (p1.age == p2.age) {
        return p1.name.compareTo(p2.name);
    }
    return Integer.compare(p1.age, p2.age);
});

list.sort((a, b) -> {
    if (a.age == b.age) {
        return a.name.compareTo(b.name); // 이름 오름차순
    }
    return a.age - b.age; // 나이 오름차순
});

5️⃣ Stream 정렬

1
2
3
4
List<String> list = Arrays.asList("apple", "banana", "kiwi", "grape");
list.stream()
    .sorted((a, b) -> b.length() - a.length()) // 길이 내림차순
    .forEach(System.out::println);

정렬 시 주의할 점

  1. int[]는 Comparator 불가 → Integer[]로 변환
  2. compare(a, b)는
    • 음수 → a < b
    • 0 → a == b
    • 양수 → a > b
  3. 문자열 비교는 compareTo() 사용 (사전순)

6️⃣ 전체 비교 정리

정렬 방법적용 대상정렬 기준성능 (평균)특징 / 비고
Arrays.sort(int[])기본형 배열 (int[], double[] 등)오름차순 (변경 불가)O(N log N)
(Dual-Pivot QuickSort)
빠르고 메모리 효율적, Comparator 불가
Arrays.sort(Integer[])참조형 배열 (Integer[], String[], 객체[])오름/내림차순
Comparator 가능
O(N log N)
(TimSort)
null 허용, Comparator로 커스텀 가능
Collections.sort(List<T>)List (ArrayList, LinkedList 등)오름/내림차순
Comparator 가능
O(N log N)
(TimSort)
내부적으로 배열로 변환 후 정렬
List.sort(Comparator)ListComparator 필수O(N log N)
(TimSort)
Java 8+, 람다 사용에 적합
Comparable 구현객체 배열 / 리스트compareTo()로 정의된 기본 정렬O(N log N)클래스 내부에서 기본 정렬 규칙 고정
Comparator 구현객체 배열 / 리스트외부에서 다중 조건 가능O(N log N)람다식 활용 가능, 다중 기준 정렬 편리
Stream.sorted()Stream 데이터기본 정렬 / ComparatorO(N log N)정렬 후 가공·출력 파이프라인 가능
This post is licensed under CC BY 4.0 by the author.