쉽게 쉽게

[Java] Collections.sort() 정렬 활용법 본문

Java/Java

[Java] Collections.sort() 정렬 활용법

곱마2 2026. 3. 6. 15:23
반응형

▤ 목차

    1. 오름/내림차순 정렬

    Collections.sort() 정렬은 List 인터페이스를 구현한 컬렉션에만 사용 가능하다. → ArrayList, LinkedList 등

    • Collections.sort(List<T> list)
    • Collections.sort(List list, Comparator comparator)
    List<String> list = new ArrayList<>(Arrays.asList("b", "a", "c"));
    
     //오름차순
     Collections.sort(list); // ["a", "b", "c"]
     list.sort(null); // Comparator를 null로 넘기면 자연 정렬 순서(Comparable)를 따름 ["a", "b", "c"] 
    
     //내림차순
     Collections.sort(list, Comparator.reverseOrder()); // ["c", "b", "a"]
     list.sort(Comparator.reverseOrder()); // ["c", "b", "a"]

    2. 사용자 정의 정렬

    1. 단일조건 정렬

    //숫자정렬
    List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 9));
    
    //오름차순
    Collections.sort(numbers);
    // [1, 3, 5, 8, 9]
    
    //내림차순
    Collections.sort(numbers, Collections.reverseOrder());
    // [9, 8, 5, 3, 1]
    
    //문자열정렬
    List<String> words = new ArrayList<>(Arrays.asList("banana", "apple", "cherry"));
    
    // 사전순 (오름차순)
    Collections.sort(words);
    // [apple, banana, cherry]
    
    // 사전 역순
    Collections.sort(words, Collections.reverseOrder());
    // [cherry, banana, apple]
    
    // 길이순
    Collections.sort(words, (a, b) -> a.length() - b.length());
    // [apple, banana, cherry]

    2. 다중조건 정렬

    다중조건으로 정렬을 진행하기 위해서는 ComparableComparator를 이용해야 한다.

    이 둘의 차이는 아래와 같다.

    • Comparable: 객체 내부에 정렬 기준을 정의할 때 (compareTo() 메서드 구현). 단 하나의 정렬 기준만 가질 수 있다.
    • Comparator: 객체 외부에 정렬 기준을 정의할 때 (compare() 메서드 구현). 여러 정렬 기준을 필요에 따라 적용할 수 있다.

    Comparable 사용법

    Student 클래스의 요소들을 아래와 같은 순서로 정렬을 해야한다고 가정하자

    • 나이 -> 이름 -> gpa

    클래스 내부에 compareTo를 오버라이드하여 정렬기준을 설정하면 Collections.sort() 사용시 compareTo() 기준으로 자동 정렬된다.

    class Student implements Comparable<Student> {
        String name;
        int age;
        double gpa;
    
        Student(String name, int age, double gpa) {
            this.name = name;
            this.age = age;
            this.gpa = gpa;
        }
    
        @Override
        public int compareTo(Student o) {
            // 1순위: 나이 오름차순
            if (this.age != o.age) return this.age - o.age;
    
            // 2순위: 이름 사전순
            if (!this.name.equals(o.name)) return this.name.compareTo(o.name);
    
            // 3순위: GPA 내림차순
            return Double.compare(o.gpa, this.gpa);
        }
    }
    List<Student> list = new ArrayList<>();
    list.add(new Student("Charlie", 20, 3.5));
    list.add(new Student("Alice",   20, 3.8));
    list.add(new Student("Bob",     19, 3.2));
    
    Collections.sort(list); // compareTo() 기준으로 자동 정렬
    
    // 결과: Bob(19), Alice(20, 3.8), Charlie(20, 3.5)

    Comparator 사용

    Comparator를 이용한 정렬은 클래스를 수정하지 않고 호출하는 쪽에서 기준을 유연하게 지정하면 된다.

     - 람다사용

    // 1순위: 나이 오름차순 / 2순위: 이름 사전순 / 3순위: GPA 내림차순
    Collections.sort(list, (a, b) -> {
        if (a.age != b.age) return a.age - b.age;
        if (!a.name.equals(b.name)) return a.name.compareTo(b.name);
        return Double.compare(b.gpa, a.gpa);
    });

     - Comparator 체이닝 사용 (가독성 향상)

    list.sort(
        Comparator.comparingInt((Student s) -> s.age)        // 1순위: 나이 오름차순
                  .thenComparing(s -> s.name)                // 2순위: 이름 사전순
                  .thenComparing(Comparator.comparingDouble((Student s) -> s.gpa).reversed()) // 3순위: GPA 내림차순
    );

    - 정렬기준 조합

    // 이름 기준으로 정렬하고 싶을 때
    Comparator<Student> byName = (a, b) -> a.name.compareTo(b.name);
    
    // GPA 기준으로 정렬하고 싶을 때
    Comparator<Student> byGpa = (a, b) -> Double.compare(b.gpa, a.gpa);
    
    // 나이 기준으로 정렬하고 싶을 때
    Comparator<Student> byAge = (a, b) -> a.age - b.age;
    
    Collections.sort(list, byName); // 이름 기준
    Collections.sort(list, byGpa);  // GPA 기준
    Collections.sort(list, byAge);  // 나이 기준
    
    // 조합도 가능
    Collections.sort(list, byAge.thenComparing(byName).thenComparing(byGpa));
    요약하면
    Comparable → 클래스 내부에 기준 정의 → 기본 정렬 하나만
    Comparator → 클래스 외부에 기준 정의 → 상황마다 다르게 적용 가능
    잘못된 내용이 있다면 지적부탁드립니다. 방문해주셔서 감사합니다.

     

    반응형