Java

Java_컬렉션 자료구조_검색기능을 강화시킨 컬렉션_Comparable 과 Comparator

ssmm95 2024. 10. 18. 10:49

Comparable : 객체 자체가 정렬기준을 갖도록 하기 위해 사용한다

객체 클래스가 Comparable 인터페이스를 구현하고 compareTo() 메서드를 정의한다 

기본정렬 방식(자연 순서)을 제공하고 한가지 기준으로만 정렬할 수 있다

 

public class Person implements Comparable<Person> {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person other) {
        return Integer.compare(this.age, other.age); // 나이 기준으로 정렬
    }
}

 

Comparator : 클래스 외부에서 졍릴 기준을 지정할 때 사용한다 

정렬 기준을 정의한 클래스를 별도로 만들거나 람다 표현식을 통해 Comparator 구현한다

여러 정렬 기준을 유영하게 정의할 수 있고, 객체의 여러 속성에 따라 다양한 정렬 방식을 정의할 수 있다

import java.util.Comparator;

public class PersonNameComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName()); // 이름 기준으로 정렬
    }
}
리턴타입 메소드 설명
int compareTo(To) 주어진 객체와 같으면 0을 리턴
주어진 객체보다 적으면 음수를 리턴
주어진 객체보다 크면 양수를 리턴

 

Comparable vs Comparator 비교

 

특징 Comparable Comparator
위치 객체 클래스 내부에 정렬 로직을 정의 외부에서 별도의 클래스로 정렬 기준을 정의
메서드 compareTo(Object o) compare(Object o1, Object o2)
정렬 기준 수 한 가지 기준으로만 정렬 가능 여러 기준으로 정렬 가능, 필요 시 여러 Comparator를 정의 가능
유연성 객체가 항상 기본 정렬 순서를 가지게 됨 클래스 외부에서 자유롭게 정렬 로직을 변경하거나 여러 정렬 기준을 적용 가능

언제 사용해야 할까?

  • Comparable: 객체의 기본 정렬 방식(예: 학생의 성적, 사원의 나이 등)을 정의할 때 사용
  • Comparator: 여러 가지 정렬 기준이 필요하거나 기존 클래스의 코드를 수정할 수 없을 때, 또는 동적으로 정렬 기준을 변경해야 할 때 사용

쉽게 말해, **Comparable**은 객체 자체가 정렬 방법을 알고 있는 경우 사용하고, **Comparator**는 객체 외부에서 다양한 정렬 방법을 유연하게 적용하고자 할 때 사용

 

원칙은 비교기능이 있는 Comparable 구현 객체를 TreeSet에 저장하거나 TreeMap의 키로 저장하는 것이다 

만약 비교기능이 없는 Comparable 비구현 객체를 저장하고 싶다면 TreeSet과 TreeMap을 생성할 때 Comparator를 제공한다 

TreeSet<E> treeSet = new TreeSet<E> ( new ComparatorImpl());

TreeMap<K,V> treeMap = new TreeMap<K,V> ( new ComparatorImp());

비교자는 Comparator 인터페이스를 구현한 객체를 말하는데, Comparator 인터페이스에는 compare() 메소드가 정의 되어있다 

비교자는 이 메소드를 재정의해서 비교 결과를 정수 값으로 리턴하면 된다 

리턴타입 메소드 설명
int compare(T o1, T o2) o1과 o2가 동등하다면 0 을 리턴
o1이 o2보다 앞에 오게 하려면 음수리턴
o1이 o2보다 뒤에 오게 하려면 양수리턴