본문 바로가기
Java 정리

[JAVA] Comparable vs Comparator 비교

by neVerThe1ess 2024. 11. 18.

 

문제를 풀다보면 Comparbale , Comparator , CompareTo, Compare 을 자주 보게 될 것이다.

보통 PriorityQueue 와 같은 우선순위 큐나 정렬을 할때 자주 사용된다. 

비슷하게 사용되는 거 같은데 언제 어떻게 사용하는지 확실하게 알고 가면 전혀 어렵지 않은 문법이다

(구구절절.. 설명하지 않겠다.. 확실하게 어떤 차이가 있고 어떻게 사용하면 되는지 위주로 설명해보겠다.)


 

Comparable , Comparator 는 인터페이스(interface) 이다. 즉 인터페이스 내에 선언된 메서드를 반드시 구현(재정의)해야한다. 

 

💡Comparable

  • 자기 자신과 매개변수 객체를 비교
  • compareTo 메소드를 사용하여 구현

CompareTo(Type o)

  • 자기자신과 o객체를 비교할 기준을 정의 
Comparable 활용법
1. 사용할 클래스에 Comparable implement(구현) 
2. 클래스 내에 비교할 변수들 생성
3. compareTo 비교를 구현한다 (재정의).

 

class Student implements Comparable<Student>
{
    int age;
    int grade;

    Student(int age , int grade)
    {
        this.age = age;
        this.grade = grade;
    }

    @Override
    public int compareTo(Student o)
    {
        //양수면 자기 자신이 큰것 , 음수면 비교객체가 큰거 , 0 이면 동일
        return this.age - o.age;
    }
}

  

compareTo 에 재정의 할 비교 구현은

위의 방식처럼 값을 빼서 양과 음으로 값을 비교해도 되고 아래 방식처럼 <>= 조건문을 활용하여 값을 비교해도 된다. 

원하는 방식 대로 설정하면 된다. (조건문을 사용하지 않을때 값이 int 허용범위 보다 커 오버플로우가 날 가능성도 있으니 주의)

if(this.age > o.age)
	return 1;
else if(this.age == o.age)
	return 0;
else 
	return -1;

 


💡Comparator

  • 두 매개변수 객체를 비교
  • compare 메소드를 사용하여 구현

compare(Type o1 , Tpye o2)

  • o1 객체와 o2 객체를 비교할 기준을 정의
Comparator 활용법
1. 사용할 클래스에 Comparator implement(구현) 
2. 클래스 내에 비교할 변수들 생성
3. compare 비교를 구현한다 (재정의).
class StudentGrade implements Comparator<StudentGrade>
{
    int age;
    int grade;

    StudentGrade(int age, int grade)
    {
        this.age  = age;
        this.grade = grade;
    }

    @Override
    public int compare(StudentGrade o1, StudentGrade o2)
    {   
    	//비교 구현
        return o1.grade - o2.grade;
    }
}

 

compare 도 compareTo와 맞게 상황에 맞게 비교 구현 해주면된다. 


//Comparable comparator 차이
/*
 * 비교하는 객체의 차이 
 * Comparable(CompareTo) : 자기자신과 매개변수 객체를 비교
 * Comparator(Compare) : 파라미터로 들어오는 두 매개변수 객체를 서로 비교
 */
import java.util.*;
public class Test 
{
    public static void main(String[] args)
    {
        Student a = new Student(10 , 3);
        Student b = new Student(11 , 4);       

        int compare = a.compareTo(b);

        if(compare == 0)
        {
            System.out.println("a 학생과 b학생 은 나이가 동갑입니다.");
        }
        else if(compare>0)
        {
            System.out.println("a 학생이 b학생 보다 나이가 많습니다.");
        }
        else
        {
            System.out.println("a 학생이 b학생 보다 나이가 어립니다.");
        }

        StudentGrade c = new StudentGrade(10,3);
        StudentGrade d = new StudentGrade(10,2);
        StudentGrade e = new StudentGrade(11,4);
        
        compare = d.compare(c,d); //d는 의미없다 c,d 만 비교

        if(compare == 0)
        {
            System.out.println("c 학생과 d 학생 같은 학년입니다.");
        }
        else if(compare>0)
        {
            System.out.println("c 학생과 d 학생 보다 고학년입니다.");
        }
        else
        {
            System.out.println("c 학생과 d 학생 보다 저학년입니다.");
        }
        }


}

//자기자신과 매개변수 객체 비교
class Student implements Comparable<Student>
{
    int age;
    int grade;

    Student(int age , int grade)
    {
        this.age = age;
        this.grade = grade;
    }

    @Override
    public int compareTo(Student o)
    {
        //양수면 자기 자신이 큰것 , 음수면 비교객체가 큰거 , 0 이면 동일
        return this.age - o.age;
    }
}

//파라미터로 입력받은 두 객체끼리 비교
class StudentGrade implements Comparator<StudentGrade>
{
    int age;
    int grade;

    StudentGrade(int age, int grade)
    {
        this.age  = age;
        this.grade = grade;
    }

    @Override
    public int compare(StudentGrade o1, StudentGrade o2)
    {   
        return o1.grade - o2.grade;
    }
}

 

결과값 

a 학생이 b학생 보다 나이가 어립니다.  (compareTo사용)
c 학생과 d 학생 보다 고학년입니다. (compare 사용) 

🚨요점 정리

1. Comparable 과 Comparator 은 인터페이스

2. Comparable 은 자기자신과 비교하는 compareTo(Type o) 사용

3. Comparator 은 두 매개변수를 비교하는 compare(Type o1, Type o2) 사용

4. compareTo, compare 모두 재정의 필수로 구현해야한다.