본문 바로가기

Language/Java

[Java] 정렬 기준 Comparator과 Comparable 에 대해 알아보겠습니다.

Comparator과 Comparable의 필요성

정렬을 하기 위해서는 '기준'이 필요합니다.

 

기본적으로 int, double 과 같은 primitive 타입의 변수는 자연스럽게 대소 관계가 존재하기 때문에 정렬 기준을 쉽게 설정할 수 있습니다. 예를 들어, 1 < 2 이므로 오름차순 정렬에서는 1, 2 순서로 정렬됩니다.

 

하지만 객체는 정렬 기준이 자동으로 존재하지 않습니다. 예를 들어, 아래와 같은 Person 클래스를 정의했다고 가정해보았습니다.

public class Person{
    int age;
    int phoneNumber;
    
    public Person(int age, int phoneNumber){
    	this.age = age;
        this.phoneNumber = phoneNumber;
    }
}

Person p1 = new Person(10, 1111);
Person p2 = new Person(20, 2222);

위의 Person 객체들을 어떻게 정렬할까요? 나이(age) 를 기준으로 할것인가, 전화번호(phoneNumber)를 기준으로 할것인가? 이때 필요한 것이 Compartor , Comparable 입니다.  이 두 인터페이스는 객체를 비교할 수 있는 기준을 정의하는 역할을 합니다.

 

Comparable 과 Comparator 의 공통점과 차이점

Comparable 과 Comparator 는 모두 인터페이스로, 객체 간의 비교를 가능하게 해줍니다. 각 인터페이스는 추상 메소드를 정의하고 있으며, 이를 구현하여 비교 기준을 명시할 수 있습니다.

 

Comparble 인터페이스

Comparable 인터페이스는 객체의 기본 정렬 기준을 정의할 때 사용합니다. java.lang 패키지에 포함되어 있으며, compareTo 메서드를 구현해야 합니다.

public interface Comparable<T>{
	int compareTo(T o);
}
 

Comparable (Java Platform SE 8 )

This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method. Lists (and arrays) of o

docs.oracle.com

  • 예를 들어, Person 클래스에서 나이(age) 를 기준으로 정렬하려면 다음과 같이 Comparable 을 구현할 수 있습니다.
public Person implements Comparable<Person>{
    int age;
    int phoneNumber;
    
    public Person(int age, int phoneNumber){
    	this.age = age;
        this.phoneNumber = phoneNumber;
    }
    
    @Override
    public int compareTo(Person p){
    	return this.age - p.age;
    }
}

여기서 compareTo 메서드는 자기 자신의 age 필드 (this.age) 와 매개 변수 객체의 age 필드(p.age) 를 비교하여 정렬합니다.

 

Compartor 인터페이스

Comparator 인터페이스는 기본 정렬 기준 외에 다른 기준으로 정렬하고자 할 때 사용합니다. java.util 패키지에 포함되어 있으며, compare 메서드를 구현해야 합니다.

public interface Comparator<T> {
    int compare(T o1, T o2);
}
 

Comparator (Java Platform SE 8 )

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. In the foregoing description, the notation sgn(expression) designates the mathematical s

docs.oracle.com

예를 들어, Person 클래스를 정렬하고 싶다면 Compartor 를 구현할 수 있습니다.

public class Person implements Comparator<Person>{
    int age;
    int phoneNumber;
    
    public Person(int age, int phoneNumber){
    	this.age = age;
        this.phoneNumber = phoneNumber;
    }
    
    @Override
    public int compare(Person p1, Person p2){
    	return p1.age - p2.age;
    }
}

여기서 compare 메서드는 두 객체 p1과 p2의 나이를 비교하여 정렬합니다.

 

자바 정렬의 기본 원리

자바는 기본적으로 오름차순으로 정렬을 수행합니다. compare 혹은 compareTo 메서드가 반환하는 값에 따라 정렬 기준이 결정됩니다.

 

a-b > 0 인 경우, 선행하는 원소가 후행하는 원소보다 큰 상태 즉 내림차순이므로 원소를 바꿉니다. 

a-b < 0 인 경우, 선행하는 원소가 후행하는 원소보다 작은 상태 즉 오름차순이므로 원소를 바꾸지 않습니다.

 

정리하자면,

compare/compareTo 메서드 값이 양수일 경우 원소를 바꿉니다.
compare/compareTo 메서드 값이 음수일 경우 원소를 바꾸지 않습니다.

 

만약 내림차순으로 정렬을 하고 싶은 경우는 반환 값을 조정해주면 됩니다.

return b-a;
return (a-b) * -1;

 

Comparator의 익명 객체(클래스)를 활용

Comparator를 통해 compare 메소드를 사용하기 위해서는 compare 메소드를 활용하기 위한 객체(comp)가 필요합니다.

public class Test {
	public static void main(String[] args)  {
 
        Person a = new Person(10, 1111);
        Person b = new Person(20, 2222);
        Person c = new Person(30, 3333);
        Person comp = new Person(0, 0); //비교만 할 객체
        
        int isBig = comp.compare(a, b);
        int isBig2 = comp.compare(b, c);
        int isBig3 = comp.compare(a, c);
		
	}
}

 

하지만 Comparator 기능만 따로 두고 싶다면 "익명 객체(이름이 정의되지 않은 객체)"를 사용하여 구현할 수도 있습니다. 즉, 이름은 정의되지 않았지만 Comparator 를 구현하는 익명 객체 (comp1) 를 생성하도록 하겠습니다.

public class Test {
	public static void main(String[] args)  {
 
        Comparator<Person> comp1 = new Comparator<Person>(){
            @Override
            public int compare(Person p1, Person p2){
            	return p1.age - p2.age;
            }
        };
    }
}

이렇게 하면 외부에서 Compartor 를 구현하는 익명 객체를 생성하여 필요한 정렬 기준을 사용할 수 있습니다.


출처 

 

자바 [JAVA] - Comparable 과 Comparator의 이해

아마 이 글을 찾아 오신 분들 대개는 Comparable과 Comparator의 차이가 무엇인지 모르거나 궁금해서 찾아오셨을 것이다. 사실 알고보면 두 개는 그렇게 어렵지 않으나 아무래도 자바를 학습하면서 객

st-lab.tistory.com

 

Comparator 와 Comparable - JAVA

처음 이 개념을 접했을 때는 뭐지.. 인터페이스는 뭐고, 객체는 뭐고 어떻게 쓰는 거지 했는데 공부하다 보니 인터페이스도 알게 되고, 객체도 알게 되니 '아! 이래서 이렇게 쓰는구나' 하고 깨달

dding9code.tistory.com

 

'Language > Java' 카테고리의 다른 글

[Java] 배열을 정렬해보겠습니다.  (0) 2023.09.13
[Java] Queue 인터페이스  (0) 2023.07.05
[Java] Stack 클래스  (0) 2023.07.05
[Java] Set 인터페이스  (0) 2023.05.15
[Java] List<E> 인터페이스  (0) 2023.05.15