java.lang.compartor

서버란·2024년 8월 31일

자바 궁금증

목록 보기
8/35
  • "객체를 비교할 수 있도록 만든다."
  • Comparator와 Comparable 인터페이스는 자바에서 객체를 정렬하는 데 사용되는 두 가지 주요 인터페이스입니다.

1. Comparable 인터페이스

Comparable 인터페이스는 객체 자체에 비교 로직을 구현할 때 사용됩니다. 즉, 클래스가 Comparable을 구현하면 그 클래스의 인스턴스들 간의 자연스러운 순서를 정의할 수 있습니다.

예제: Student 클래스에서 Comparable 구현

  • Student 클래스
class Student implements Comparable<Student> {
    int studentNo;
    String name;

    public Student(int studentNo, String name) {
        this.studentNo = studentNo;
        this.name = name;
    }

    public int getStudentNo() {
        return studentNo;
    }

    public String getName() {
        return name;
    }

    @Override
    public int compareTo(Student other) {
        // 학생 번호(studentNo)를 기준으로 오름차순 정렬
        return Integer.compare(this.studentNo, other.studentNo);
    }

    @Override
    public String toString() {
        return "Student No: " + studentNo + ", Name: " + name;
    }
}
  • Main 클래스
public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(3, "Charlie"));
        students.add(new Student(1, "Alice"));
        students.add(new Student(2, "Bob"));

        // Comparable에 의해 정렬됨
        Collections.sort(students);

        for (Student student : students) {
            System.out.println(student);
        }
    }
}

출력:
Student No: 1, Name: Alice
Student No: 2, Name: Bob
Student No: 3, Name: Charlie

  • 이 예제에서 Student 클래스는 Comparable 인터페이스를 구현하고 있으며, compareTo 메서드에서 학생 번호(studentNo)를 기준으로 오름차순 정렬을 정의하고 있습니다. Collections.sort()를 호출하면 Student 클래스의 compareTo 메서드에 따라 리스트가 정렬됩니다.

2. Comparator 인터페이스

  • Comparator 인터페이스는 특정 기준에 따라 객체를 정렬할 수 있도록 외부에서 비교 로직을 정의할 때 사용됩니다.
    이는 객체가 여러 가지 기준으로 정렬될 수 있는 경우 유용합니다.

예제: Student 클래스에서 Comparator 구현

  • Class
import java.util.Comparator;

class StudentNoComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        // 학생 번호(studentNo)를 기준으로 오름차순 정렬
        return Integer.compare(s1.getStudentNo(), s2.getStudentNo());
    }
}

class StudentNameComparator implements Comparator<Student> {
    @Override
    public int compare(Student s1, Student s2) {
        // 학생 이름(name)을 기준으로 사전순 정렬
        return s1.getName().compareTo(s2.getName());
    }
}
  • Main 클래스
public class Main {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student(3, "Charlie"));
        students.add(new Student(1, "Alice"));
        students.add(new Student(2, "Bob"));

        // 학생 번호 기준 정렬
        Collections.sort(students, new StudentNoComparator());
        System.out.println("Sorted by Student Number:");
        for (Student student : students) {
            System.out.println(student);
        }

        // 학생 이름 기준 정렬
        Collections.sort(students, new StudentNameComparator());
        System.out.println("\nSorted by Name:");
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

출력:
Sorted by Student Number:
Student No: 1, Name: Alice
Student No: 2, Name: Bob
Student No: 3, Name: Charlie

Sorted by Name:
Student No: 1, Name: Alice
Student No: 2, Name: Bob
Student No: 3, Name: Charlie
이 예제에서는 두 개의 Comparator를 정의했습니다:

  • StudentNoComparator: 학생 번호를 기준으로 정렬합니다.
  • StudentNameComparator: 학생 이름을 기준으로 정렬합니다.
  • Collections.sort(students, new StudentNoComparator())
    또는 Collections.sort(students, new StudentNameComparator())를
    호출하면 각 기준에 따라 학생 리스트가 정렬됩니다.
  • 차이점 요약
    Comparable: 객체의 자연스러운 순서를 정의하기 위해 클래스 내에서 compareTo 메서드를 구현합니다.
    Comparator: 외부에서 객체를 비교하기 위한 방법을 정의하며, 여러 가지 기준으로 객체를 정렬할 수 있습니다.

Comparator를 안에서 쓰는 법

import java.io.*;
import java.util.*;

class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        String[][] persons = new String[n][2];
        for (int i = 0; i < n ; i++){
            StringTokenizer st = new StringTokenizer(br.readLine());
            persons[i][0] = st.nextToken();
            persons[i][1] = st.nextToken();
        }

        Arrays.sort(persons, new Comparator<String[]>() {
            @Override
            public int compare(String[]o1, String[]o2) {
                return Integer.parseInt(o1[0]) - Integer.parseInt(o2[0]);
            }
        });
        for(int i = 0; i < persons.length; i++){
            System.out.println(persons[i][0] + " " + persons[i][1]);
        }
    }
}
  • Arrays.sort 메서드를 사용하여 배열을 정렬하는 또 다른 방법은 Comparator 인터페이스의 구현체를 제공하는 것입니다.
  • 이 방법은 람다 표현식을 사용하는 대신, 익명 클래스 또는 명시적으로 구현한 클래스를 사용하는 방법입니다.

아래는 Comparator를 명시적으로 구현하는 방법과 그 동작에 대한 자세한 설명입니다:

Arrays.sort(persons, new Comparator<String[]>() {
    @Override
    public int compare(String[] o1, String[] o2) {
        return Integer.parseInt(o1[0]) - Integer.parseInt(o2[0]);
    }
});

설명

  1. Arrays.sort 메서드:

    Arrays.sort는 배열을 정렬하는 자바 메서드입니다.
    두 번째 인자로 Comparator를 제공하면, 이 Comparator를 사용하여 배열을 정렬할 수 있습니다.

  2. Comparator 인터페이스:

    Comparator는 두 객체를 비교하기 위한 함수형 인터페이스입니다.
    compare 메서드를 구현하여 두 객체 간의 정렬 순서를 정의합니다.

  3. 익명 클래스 구현:

    new Comparator<String[]>() { ... } 부분은 Comparator 인터페이스를 구현하는 익명 클래스를 정의합니다.
    익명 클래스는 클래스를 정의하고 인스턴스를 생성하는 과정을 한 줄로 작성할 수 있게 해줍니다. 여기서는 Comparator<String[]>를 구현하는 익명 클래스를 사용하여 정렬 기준을 설정합니다.

  4. compare 메서드:

    • compare 메서드는 두 개의 String[] 배열을 비교합니다.
    • o1과 o2는 각각 비교할 두 배열입니다.
    • Integer.parseInt(o1[0])는 o1 배열의 첫 번째 요소를 정수로 변환합니다.
    • Integer.parseInt(o2[0])는 o2 배열의 첫 번째 요소를 정수로 변환합니다.
    • Integer.parseInt(o1[0]) - Integer.parseInt(o2[0])는 두 정수 간의 차이를 계산하여 반환합니다. 이 차이는 정렬 순서를 결정합니다:
      • 음수: o1이 o2보다 먼저 오도록 정렬합니다.
      • 양수: o1이 o2보다 나중에 오도록 정렬합니다.
      • 0: 두 배열의 순서를 변경하지 않습니다.
profile
백엔드에서 서버엔지니어가 된 사람

0개의 댓글