Comparator 와 Comparable

JavaBeginner
지금 연습하기

소개

Java 애플리케이션에서 객체를 비교하고 정렬해야 하는 경우가 많습니다. 정수나 문자열과 같은 기본 데이터 타입의 경우, Java 는 이미 이러한 타입들을 비교하는 방법을 알고 있습니다. 하지만 사용자 정의 객체의 경우, Java 에게 객체를 어떻게 비교하고 정렬해야 하는지 알려줘야 합니다.

Java 는 이를 돕기 위해 두 가지 인터페이스를 제공합니다.

  • Comparable 인터페이스는 클래스가 자체적인 자연 순서를 정의할 수 있도록 합니다.
  • Comparator 인터페이스는 다양한 정렬 기준에 사용할 수 있는 외부 비교 로직을 제공합니다.

이 Lab 에서는 두 인터페이스를 모두 구현하고, 이를 사용하여 다양한 방식으로 객체 컬렉션을 정렬하는 방법을 배우게 됩니다.

이것은 가이드 실험입니다. 학습과 실습을 돕기 위한 단계별 지침을 제공합니다.각 단계를 완료하고 실무 경험을 쌓기 위해 지침을 주의 깊게 따르세요. 과거 데이터에 따르면, 이것은 중급 레벨의 실험이며 완료율은 55%입니다.학습자들로부터 100%의 긍정적인 리뷰율을 받았습니다.

Comparable 인터페이스 이해하기

Comparable 인터페이스는 클래스에 자연 순서가 있을 때 사용됩니다. 예를 들어, 문자열은 자연스럽게 알파벳 순으로 정렬되고, 정수는 숫자 순으로 정렬됩니다.

클래스가 Comparable 인터페이스를 구현할 때, 클래스의 인스턴스가 어떻게 정렬되어야 하는지 지정하는 compareTo() 메서드를 정의해야 합니다.

기본 Student 클래스 생성하기

Comparable 인터페이스를 사용하는 방법을 보여주기 위해 간단한 Student 클래스를 만들어 보겠습니다. 이름, GPA 및 등록 번호가 있는 학생을 정의합니다.

  1. WebIDE 를 열고 ~/project 디렉토리에 다음 코드를 사용하여 Student.java라는 새 파일을 만듭니다.
public class Student implements Comparable<Student> {
    private String name;
    private double gpa;
    private int regNo;

    public Student(String name, double gpa, int regNo) {
        this.name = name;
        this.gpa = gpa;
        this.regNo = regNo;
    }

    // Implementing the compareTo method from Comparable interface
    @Override
    public int compareTo(Student other) {
        // Compare students based on GPA
        if (this.gpa < other.gpa) {
            return -1;
        } else if (this.gpa > other.gpa) {
            return 1;
        } else {
            return 0;
        }
    }

    // Getters
    public String getName() {
        return name;
    }

    public double getGpa() {
        return gpa;
    }

    public int getRegNo() {
        return regNo;
    }

    @Override
    public String toString() {
        return name + ", GPA: " + gpa + ", Reg No: " + regNo;
    }
}

이 코드를 이해해 봅시다.

  • Student 클래스는 Comparable<Student> 인터페이스를 구현합니다.
  • compareTo() 메서드는 학생을 GPA 를 기준으로 비교합니다.
  • 현재 학생의 GPA 가 다른 학생의 GPA 보다 작으면 -1 을 반환합니다.
  • 현재 학생의 GPA 가 다른 학생의 GPA 보다 크면 1 을 반환합니다.
  • GPA 가 같으면 0 을 반환합니다.

이제 Comparable 인터페이스를 사용하여 학생을 정렬하는 방법을 보기 위해 간단한 테스트 프로그램을 만들어 보겠습니다.

  1. ~/project 디렉토리에 다음 코드를 사용하여 ComparableDemo.java라는 새 파일을 만듭니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparableDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort the list using the natural ordering (defined by compareTo method)
        Collections.sort(students);

        // Print the sorted list
        System.out.println("\nStudents sorted by GPA (using Comparable):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

이 프로그램은 다음을 수행합니다.

  1. Student 객체 목록을 생성합니다.

  2. 정렬되지 않은 목록을 출력합니다.

  3. compareTo() 메서드에 의해 정의된 자연 순서를 사용하여 Collections.sort()를 사용하여 목록을 정렬합니다.

  4. 정렬된 목록을 출력합니다.

  5. 이제 코드를 컴파일하고 실행하여 출력을 확인해 보겠습니다.

cd ~/project
javac Student.java ComparableDemo.java
java ComparableDemo

다음과 유사한 출력을 볼 수 있습니다.

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104

Students sorted by GPA (using Comparable):
Alice, GPA: 3.2, Reg No: 103
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Bob, GPA: 3.9, Reg No: 104

보시다시피, 학생들은 이제 compareTo() 메서드에서 정의한 자연 순서에 따라 GPA 오름차순으로 정렬됩니다.

Comparator 생성 및 사용

Comparable 인터페이스는 클래스에 자연 순서를 정의하는 반면, 때로는 다른 기준에 따라 객체를 정렬해야 할 필요가 있습니다. 이때 Comparator 인터페이스가 사용됩니다.

Comparator 인터페이스를 사용하면 비교되는 클래스와 별개로 사용자 정의 정렬 로직을 정의할 수 있습니다. 즉, 동일한 클래스 객체를 정렬하는 여러 가지 방법을 가질 수 있습니다.

이름 기반 정렬을 위한 Comparator 생성하기

학생을 이름순으로 알파벳순으로 정렬하는 Comparator를 만들어 보겠습니다.

  1. ~/project 디렉토리에 다음 코드를 사용하여 StudentNameComparator.java라는 새 파일을 만듭니다.
import java.util.Comparator;

public class StudentNameComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        // Compare students based on their names
        return s1.getName().compareTo(s2.getName());
    }
}

Comparator는 다음을 수행합니다.

  • Comparator<Student> 인터페이스를 구현합니다.
  • 두 개의 Student 객체를 받는 compare() 메서드를 정의합니다.
  • String 클래스의 자체 compareTo() 메서드를 사용하여 학생을 이름별로 비교합니다.
  1. 이제 이 Comparator를 사용하는 방법을 보여주는 프로그램을 만들어 보겠습니다. ~/project 디렉토리에 ComparatorDemo.java라는 파일을 만듭니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ComparatorDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort by name using the StudentNameComparator
        Collections.sort(students, new StudentNameComparator());

        // Print the list sorted by name
        System.out.println("\nStudents sorted by name (using Comparator):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

이 프로그램은 다음을 수행합니다.

  1. Student 객체 목록을 생성합니다.

  2. 정렬되지 않은 목록을 출력합니다.

  3. 사용자 정의 StudentNameComparator를 사용하여 Collections.sort()로 목록을 정렬합니다.

  4. 정렬된 목록을 출력합니다.

  5. 코드를 컴파일하고 실행해 보겠습니다.

cd ~/project
javac Student.java StudentNameComparator.java ComparatorDemo.java
java ComparatorDemo

다음과 유사한 출력을 볼 수 있습니다.

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104

Students sorted by name (using Comparator):
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102

보시다시피, 학생들은 이제 GPA 가 아닌 이름순으로 알파벳순으로 정렬됩니다.

람다 표현식을 사용하여 Comparator 사용하기

Java 8 은 람다 표현식을 도입하여 comparator 를 생성하는 것을 단순화할 수 있습니다. 별도의 클래스를 생성하는 대신, 비교 로직을 인라인으로 정의할 수 있습니다.

  1. ~/project 디렉토리에 LambdaComparatorDemo.java라는 새 파일을 만듭니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class LambdaComparatorDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));

        // Sort by registration number using lambda expression
        Collections.sort(students, (s1, s2) -> s1.getRegNo() - s2.getRegNo());

        // Print the list sorted by registration number
        System.out.println("Students sorted by registration number (using lambda):");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort by name using method reference
        Collections.sort(students, Comparator.comparing(Student::getName));

        // Print the list sorted by name
        System.out.println("\nStudents sorted by name (using method reference):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

이 프로그램은 다음을 보여줍니다.

  1. 람다 표현식을 사용하여 학생을 등록 번호별로 정렬하는 comparator 를 생성합니다.

  2. Comparator.comparing() 메서드를 메서드 참조와 함께 사용하여 학생을 이름별로 정렬하는 comparator 를 생성합니다.

  3. 이 코드를 컴파일하고 실행합니다.

cd ~/project
javac Student.java LambdaComparatorDemo.java
java LambdaComparatorDemo

다음과 유사한 출력을 볼 수 있습니다.

Students sorted by registration number (using lambda):
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104

Students sorted by name (using method reference):
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102

학생들은 먼저 등록 번호별로 정렬된 다음 이름별로 정렬됩니다.

고급 정렬 기법

실제 응용 프로그램에서는 다음과 같은 더 복잡한 정렬 로직이 필요한 경우가 많습니다.

  • 여러 기준별 정렬 (예: GPA 별 정렬, GPA 가 같으면 이름별 정렬)
  • 역순 정렬
  • 사용자 정의 comparator 체인 생성

이러한 고급 기술을 살펴보겠습니다.

여러 기준별 정렬

  1. ~/project 디렉토리에 MultiCriteriaDemo.java라는 새 파일을 만듭니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class MultiCriteriaDemo {
    public static void main(String[] args) {
        // Create a list of students with some having the same GPA
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
        students.add(new Student("Bob", 3.8, 104));   // Same GPA as Mary
        students.add(new Student("Charlie", 3.2, 105));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Sort first by GPA, then by name
        Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
        Comparator<Student> byName = Comparator.comparing(Student::getName);

        // Combine the comparators using thenComparing
        Comparator<Student> byGpaThenName = byGpa.thenComparing(byName);

        // Sort the list
        Collections.sort(students, byGpaThenName);

        // Print the sorted list
        System.out.println("\nStudents sorted by GPA, then by name:");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

이 프로그램은 다음을 수행합니다.

  1. 일부 학생이 동일한 GPA 를 갖는 학생 목록을 생성합니다.

  2. GPA 에 대한 comparator 와 이름에 대한 comparator 를 생성합니다.

  3. thenComparing() 메서드를 사용하여 이러한 comparator 를 결합합니다.

  4. 먼저 GPA 별로, GPA 가 같으면 이름별로 학생을 정렬합니다.

  5. 코드를 컴파일하고 실행합니다.

cd ~/project
javac Student.java MultiCriteriaDemo.java
java MultiCriteriaDemo

다음과 유사한 출력을 볼 수 있습니다.

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105

Students sorted by GPA, then by name:
Charlie, GPA: 3.2, Reg No: 105
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102

GPA 가 같은 학생 (Alice 와 John 은 3.5, Bob 과 Mary 는 3.8) 이 알파벳순으로 정렬되는 것을 확인하십시오.

역순 정렬

  1. ~/project 디렉토리에 ReverseOrderDemo.java라는 새 파일을 만듭니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ReverseOrderDemo {
    public static void main(String[] args) {
        // Create a list of students
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.2, 103));
        students.add(new Student("Bob", 3.9, 104));
        students.add(new Student("Charlie", 3.0, 105));

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Method 1: Using Collections.reverseOrder() with a comparator
        Comparator<Student> byGpa = Comparator.comparing(Student::getGpa);
        Comparator<Student> byGpaReversed = Collections.reverseOrder(byGpa);

        Collections.sort(students, byGpaReversed);

        System.out.println("\nStudents sorted by GPA in descending order (Method 1):");
        for (Student student : students) {
            System.out.println(student);
        }

        // Method 2: Using the reversed() method of Comparator
        Collections.sort(students, Comparator.comparing(Student::getName).reversed());

        System.out.println("\nStudents sorted by name in reverse alphabetical order (Method 2):");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

이 프로그램은 역순으로 정렬하는 두 가지 방법을 보여줍니다.

  1. Collections.reverseOrder()를 사용하여 comparator 를 반전시킵니다.

  2. comparator 의 reversed() 메서드를 사용합니다.

  3. 코드를 컴파일하고 실행합니다.

cd ~/project
javac Student.java ReverseOrderDemo.java
java ReverseOrderDemo

다음과 유사한 출력을 볼 수 있습니다.

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.2, Reg No: 103
Bob, GPA: 3.9, Reg No: 104
Charlie, GPA: 3.0, Reg No: 105

Students sorted by GPA in descending order (Method 1):
Bob, GPA: 3.9, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Alice, GPA: 3.2, Reg No: 103
Charlie, GPA: 3.0, Reg No: 105

Students sorted by name in reverse alphabetical order (Method 2):
Mary, GPA: 3.8, Reg No: 102
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.0, Reg No: 105
Bob, GPA: 3.9, Reg No: 104
Alice, GPA: 3.2, Reg No: 103

첫 번째 정렬은 GPA 별로 내림차순으로 학생을 보여주고, 두 번째 정렬은 이름별로 역 알파벳순으로 학생을 보여줍니다.

복잡한 정렬 체인

  1. 여러 기준과 역순 정렬을 결합하는 또 다른 예제를 만들어 보겠습니다. ~/project 디렉토리에 ComplexSortingDemo.java라는 파일을 만듭니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ComplexSortingDemo {
    public static void main(String[] args) {
        // Create a list of students with varied data
        List<Student> students = new ArrayList<>();
        students.add(new Student("John", 3.5, 101));
        students.add(new Student("Mary", 3.8, 102));
        students.add(new Student("Alice", 3.5, 103)); // Same GPA as John
        students.add(new Student("Bob", 3.8, 104));   // Same GPA as Mary
        students.add(new Student("Charlie", 3.2, 105));
        students.add(new Student("David", 3.2, 106)); // Same GPA as Charlie

        // Print the unsorted list
        System.out.println("Unsorted Student List:");
        for (Student student : students) {
            System.out.println(student);
        }

        // Create a complex sorting chain:
        // 1. Sort by GPA in descending order
        // 2. If GPAs are equal, sort by name in ascending order
        // 3. If names are also equal, sort by registration number in descending order
        Comparator<Student> complexComparator = Comparator
            .comparing(Student::getGpa, Comparator.reverseOrder())
            .thenComparing(Student::getName)
            .thenComparing(Student::getRegNo, Comparator.reverseOrder());

        Collections.sort(students, complexComparator);

        System.out.println("\nStudents sorted by complex criteria:");
        System.out.println("(GPA descending, then name ascending, then reg. number descending)");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

이 프로그램은 다음을 수행하는 복잡한 정렬 체인을 생성합니다.

  1. 먼저 GPA 별로 내림차순으로 학생을 정렬합니다.

  2. GPA 가 같으면 이름별로 오름차순으로 정렬합니다.

  3. GPA 와 이름이 모두 같으면 등록 번호별로 내림차순으로 정렬합니다.

  4. 코드를 컴파일하고 실행합니다.

cd ~/project
javac Student.java ComplexSortingDemo.java
java ComplexSortingDemo

다음과 유사한 출력을 볼 수 있습니다.

Unsorted Student List:
John, GPA: 3.5, Reg No: 101
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
Bob, GPA: 3.8, Reg No: 104
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106

Students sorted by complex criteria:
(GPA descending, then name ascending, then reg. number descending)
Bob, GPA: 3.8, Reg No: 104
Mary, GPA: 3.8, Reg No: 102
Alice, GPA: 3.5, Reg No: 103
John, GPA: 3.5, Reg No: 101
Charlie, GPA: 3.2, Reg No: 105
David, GPA: 3.2, Reg No: 106

이 출력에서:

  • Bob 과 Mary 는 모두 GPA 가 3.8 이지만 Bob 이 알파벳순으로 먼저 옵니다.
  • Alice 와 John 은 모두 GPA 가 3.5 이지만 Alice 가 알파벳순으로 먼저 옵니다.
  • Charlie 와 David 는 모두 GPA 가 3.2 이고 Charlie 가 알파벳순으로 먼저 옵니다.

이것은 comparator 를 연결하여 복잡하고 다단계 정렬 로직을 생성할 수 있는 방법을 보여줍니다.

완전한 정렬 애플리케이션 구축

Comparable 인터페이스, Comparator 인터페이스 및 다양한 정렬 기술에 대해 배웠으므로 모든 것을 완전한 애플리케이션으로 통합해 보겠습니다.

다양한 방식으로 학생을 정렬할 수 있는 학생 관리 시스템을 만들 것입니다.

  1. 먼저, Student 클래스의 업데이트된 버전을 만들어 보겠습니다. 이 버전은 Comparable을 구현하고 더 나은 표시를 위해 개선된 toString() 메서드를 포함합니다. ~/project 디렉토리에 StudentManager.java라는 파일을 만듭니다.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

class Student implements Comparable<Student> {
    private String name;
    private double gpa;
    private int regNo;
    private String major;

    public Student(String name, double gpa, int regNo, String major) {
        this.name = name;
        this.gpa = gpa;
        this.regNo = regNo;
        this.major = major;
    }

    @Override
    public int compareTo(Student other) {
        // Default natural ordering by registration number
        return this.regNo - other.regNo;
    }

    // Getters
    public String getName() {
        return name;
    }

    public double getGpa() {
        return gpa;
    }

    public int getRegNo() {
        return regNo;
    }

    public String getMajor() {
        return major;
    }

    @Override
    public String toString() {
        return String.format("%-10s | GPA: %.1f | Reg No: %-5d | Major: %-10s",
                            name, gpa, regNo, major);
    }
}

public class StudentManager {
    private List<Student> students;

    public StudentManager() {
        students = new ArrayList<>();
        // Add some sample students
        students.add(new Student("John", 3.5, 101, "Computer Science"));
        students.add(new Student("Mary", 3.8, 102, "Physics"));
        students.add(new Student("Alice", 3.5, 103, "Mathematics"));
        students.add(new Student("Bob", 3.9, 104, "Computer Science"));
        students.add(new Student("Charlie", 3.2, 105, "Physics"));
        students.add(new Student("David", 3.6, 106, "Mathematics"));
        students.add(new Student("Eve", 3.8, 107, "Biology"));
    }

    public void displayStudents() {
        System.out.println("----------------------------------------------------------");
        System.out.println("Name       | GPA   | Reg No | Major      ");
        System.out.println("----------------------------------------------------------");
        for (Student student : students) {
            System.out.println(student);
        }
        System.out.println("----------------------------------------------------------");
    }

    public void sortByNaturalOrder() {
        Collections.sort(students);
        System.out.println("\nStudents sorted by registration number (natural order):");
        displayStudents();
    }

    public void sortByName() {
        Collections.sort(students, Comparator.comparing(Student::getName));
        System.out.println("\nStudents sorted by name:");
        displayStudents();
    }

    public void sortByGpaDescending() {
        Collections.sort(students, Comparator.comparing(Student::getGpa).reversed());
        System.out.println("\nStudents sorted by GPA (descending):");
        displayStudents();
    }

    public void sortByMajorThenGpa() {
        Collections.sort(students,
            Comparator.comparing(Student::getMajor)
                     .thenComparing(Student::getGpa, Comparator.reverseOrder()));
        System.out.println("\nStudents sorted by major, then by GPA (descending):");
        displayStudents();
    }

    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
        Scanner scanner = new Scanner(System.in);

        while (true) {
            System.out.println("\nStudent Manager");
            System.out.println("1. Display students (unsorted)");
            System.out.println("2. Sort by registration number");
            System.out.println("3. Sort by name");
            System.out.println("4. Sort by GPA (highest first)");
            System.out.println("5. Sort by major, then by GPA (highest first)");
            System.out.println("6. Exit");
            System.out.print("Enter your choice: ");

            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    System.out.println("\nUnsorted student list:");
                    manager.displayStudents();
                    break;
                case 2:
                    manager.sortByNaturalOrder();
                    break;
                case 3:
                    manager.sortByName();
                    break;
                case 4:
                    manager.sortByGpaDescending();
                    break;
                case 5:
                    manager.sortByMajorThenGpa();
                    break;
                case 6:
                    System.out.println("Exiting program. Goodbye!");
                    scanner.close();
                    return;
                default:
                    System.out.println("Invalid choice. Please try again.");
            }
        }
    }
}

이 애플리케이션은 다음을 수행합니다.

  1. 이름, GPA, 등록 번호 및 전공이 있는 Student 클래스를 정의합니다.

  2. 등록 번호별 자연 순서를 정의하기 위해 Comparable을 구현합니다.

  3. 학생 목록을 유지하는 StudentManager 클래스를 생성합니다.

  4. 다양한 방식으로 학생을 정렬하는 메서드를 제공합니다.

  5. 사용자가 다양한 정렬 옵션을 선택할 수 있는 간단한 메뉴 기반 인터페이스를 포함합니다.

  6. 애플리케이션을 컴파일하고 실행합니다.

cd ~/project
javac StudentManager.java
java StudentManager
  1. 다양한 정렬 옵션을 시도하여 애플리케이션을 테스트합니다. 다음은 샘플 상호 작용입니다.
Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 1

Unsorted student list:
----------------------------------------------------------
Name       | GPA   | Reg No | Major
----------------------------------------------------------
John       | GPA: 3.5 | Reg No: 101   | Major: Computer Science
Mary       | GPA: 3.8 | Reg No: 102   | Major: Physics
Alice      | GPA: 3.5 | Reg No: 103   | Major: Mathematics
Bob        | GPA: 3.9 | Reg No: 104   | Major: Computer Science
Charlie    | GPA: 3.2 | Reg No: 105   | Major: Physics
David      | GPA: 3.6 | Reg No: 106   | Major: Mathematics
Eve        | GPA: 3.8 | Reg No: 107   | Major: Biology
----------------------------------------------------------

Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 3

Students sorted by name:
----------------------------------------------------------
Name       | GPA   | Reg No | Major
----------------------------------------------------------
Alice      | GPA: 3.5 | Reg No: 103   | Major: Mathematics
Bob        | GPA: 3.9 | Reg No: 104   | Major: Computer Science
Charlie    | GPA: 3.2 | Reg No: 105   | Major: Physics
David      | GPA: 3.6 | Reg No: 106   | Major: Mathematics
Eve        | GPA: 3.8 | Reg No: 107   | Major: Biology
John       | GPA: 3.5 | Reg No: 101   | Major: Computer Science
Mary       | GPA: 3.8 | Reg No: 102   | Major: Physics
----------------------------------------------------------

Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 5

Students sorted by major, then by GPA (descending):
----------------------------------------------------------
Name       | GPA   | Reg No | Major
----------------------------------------------------------
Eve        | GPA: 3.8 | Reg No: 107   | Major: Biology
Bob        | GPA: 3.9 | Reg No: 104   | Major: Computer Science
John       | GPA: 3.5 | Reg No: 101   | Major: Computer Science
David      | GPA: 3.6 | Reg No: 106   | Major: Mathematics
Alice      | GPA: 3.5 | Reg No: 103   | Major: Mathematics
Mary       | GPA: 3.8 | Reg No: 102   | Major: Physics
Charlie    | GPA: 3.2 | Reg No: 105   | Major: Physics
----------------------------------------------------------

Student Manager
1. Display students (unsorted)
2. Sort by registration number
3. Sort by name
4. Sort by GPA (highest first)
5. Sort by major, then by GPA (highest first)
6. Exit
Enter your choice: 6
Exiting program. Goodbye!

다양한 정렬 옵션을 실험하여 학생 목록이 매번 다르게 표시되는 방식을 확인할 수 있습니다.

이 완전한 애플리케이션은 Java 에서 ComparableComparator 인터페이스의 강력함과 유연성을 보여줍니다. 애플리케이션의 다양한 요구 사항을 충족하기 위해 다양한 방식으로 객체를 정렬할 수 있습니다.

요약

이 랩에서는 ComparableComparator 인터페이스를 사용하여 Java 에서 객체를 비교하고 정렬하는 방법을 배웠습니다.

주요 개념:

  1. Comparable 인터페이스

    • compareTo() 메서드를 구현하여 클래스의 자연 순서 정의
    • 자연 순서가 지정된 객체와 함께 Collections.sort() 사용
  2. Comparator 인터페이스

    • 다양한 정렬 기준에 대한 사용자 정의 comparator 생성
    • 사용자 정의 comparator 와 함께 Collections.sort() 사용
    • 간결한 comparator 생성을 위한 람다 표현식 및 메서드 참조 사용
  3. 고급 정렬 기술

    • thenComparing()을 사용하여 여러 기준별 정렬
    • Collections.reverseOrder() 또는 reversed()를 사용하여 역순 정렬
    • 복잡한 정렬 체인 생성
  4. 실용적인 응용

    • 다양한 정렬 옵션을 갖춘 완전한 학생 관리 시스템 구축
    • 다양한 정렬 기능을 시연하기 위한 사용자 인터페이스 구현

이러한 정렬 기능은 많은 Java 애플리케이션, 특히 데이터 모음을 처리하는 애플리케이션에 필수적입니다. 학생 관리 시스템에서 학생을 정렬하든, 전자 상거래 애플리케이션에서 주문을 정렬하든, 다른 유형의 데이터를 정렬하든, 이 랩에서 배운 기술은 효율적이고 유연한 정렬 로직을 구현하는 데 도움이 될 것입니다.