Java

Comparator 인터페이스 와 Comparable 인터페이스

bang2001 2013. 7. 25. 09:24

Comparator 인터페이스 와 Comparable 인터페이스


Comparable 인터페이스 객체의 비교를 위한 인터페이스로 
객체간에 순서나 정렬을 하기 우해서 Comparable 인터페이스를 구현해야 한다.

구현하는 방법은 Comparable 인터페이스를 객체비교를 구현할 클래스에 implements (상속)하고,
int compareTo(T o) 메소드를 재정의 해야한다. 
이때 재정의 하면서 내부적으로 객체를 비교하여 어떻게 순서가 정해질지에 대해서 구현하면 된다.
※ 현재의 객체가 다른객체와 비교하여 최종 반환되는 값이 0이면 순서가 같음을 의미하고, 반환되는 값이 양수이면 순서가 뒤에 위치함을 의미하고, 반환되는 값이 음수이면 순서가 앞에 있음을 의미한다. 비교하는 주체는 해당 메소드를 호출하는 객체가 주체자가 되고, 비교대상은 주체자를 제외한 다른 객체를 의미한다.

ex) Person이라는 클래스에서 나이에 의한 비교를 구현한다고 가정했을 때이다.

@Override
public int compareTo(Object o) // 가급적이면 이렇게 하지말고 제네릭을 이용하는것이 
                                                        에러를 사전에 차단에 방지할 수 있다.
{
int inAge = ((Person)o).getAge(); // 위에서 Object로 매개변수로 받아왔기 떄문에 
                                                                    형변환이 필요하다.
return result = age - inAge; // 맴버변수 age(현재 객체의 변수)와 매개변수로 받은 
                                                      객체의 맴버변수(inAge)를 비교한다.
}

Comparator 인터페이스는 Comparable 인터페이스처럼 객체비교를 구현하기 위한 인터페이스이다.
객체 비교를 위해서 int compare(T o1, T o2) 메소드를 재정의해야 한다.
※ o1 객체와 o2 객체보다 순서가 앞이면 양수, 같으면 0, 뒤이면 음수를 반환한다.
    여기서는 o1이 비교하는 주체자가 되고, o2가 비교대상자가 된다.

    ex) 문자열에 대한 사전적 편찬의 순서를 적용하여 정렬을 구현한다고 가정했을 때이다.

@Override
public int compare(String s1, String s2)
{
return s2.compareToIgnoreCase(s1); //compareToIgnoreCase() 메소드는 문자열의 
                                                                        대해서 사전적 편찬상으로
}    //정해진 순서에 의해 두개의 문자열에 대한 순서차이를 
                                                      int형으로 반환하는 메소드이다.

이 두개의 인터페이스의 차이점은 다음과 같다.

Comparable 와 Comparator 인터페이스는 객체를 비교하기 위한 인터페이스이다. 그렇다면 왜 이렇게 따로 존재하는것일까? 그 이유는 비교하는 기준에 따라서 틀리다. Comparable은 자기자신과 같은 클래스 타입의 다른객체와 비교하기 위해서 사용되고, Comparator 은 다른 두개의 객체를 비교.. 즉
Comparator 를 구현한 객체가 다른 두개의 객체를 비교하는 기준이 되어 두개의 객체를 비교한다.
주로 어떤 특정 객체에 대한 객체비교의 기준점을 제시할 때 쓰인다.

다음 예시를 보자.(인터넷에서 다른사람이 작성한 코드입니다.)

------------------------------------------------------------------------------------------

import java.util.Arrays;
import java.util.Comparator;

class Person implements Comparable<Person> {
  public Person(String firstName, String surname) {
    this.firstName = firstName;
    this.surname = surname;
  }
  public String getFirstName() {
    return firstName;
  }
  public String getSurname() {
    return surname;
  }
  public String toString() {
    return firstName + " " + surname;
  }
  public int compareTo(Person person) {
    int result = surname.compareTo(person.surname);
    return result == ? firstName.compareTo(((Personperson).firstName: result;
  }
  private String firstName;
  private String surname;
}

class ComparePersons implements Comparator<Person> {
  // Method to compare Person objects - order is descending
  public int compare(Person person1, Person person2) {
    int result = -person1.getSurname().compareTo(person2.getSurname());
    return result == ? -person1.getFirstName().compareTo(person2.getFirstName()) 
result;

  }
  // Method to compare with another comparator
  public boolean equals(Object collator) {
    if (this == collator) { // If argument is the same object
      return true// then it must be equal
    }
    if (collator == null) { // If argument is null
      return false// then it can't be equal
    }
    return getClass() == collator.getClass()// Class must be the same for
                                              // equal
  }
}
public class MainClass {
  public static void main(String[] args) {
    Person[] authors = new Person("A""S")
                         new Person("J""G"),
                         new Person("T""C")
                         new Person("C""S"),        
                         new Person("P""C")
                         new Person("B""B") };
    System.out.println("Original order:");
    for (Person author : authors) {
      System.out.println(author);
    }
    Arrays.sort(authors, new ComparePersons())// Sort using comparator
    System.out.println("\nOrder after sorting using comparator:");
    for (Person author : authors) {
      System.out.println(author);
    }
    Arrays.sort(authors)// Sort using Comparable method
    System.out.println("\nOrder after sorting using Comparable method:");
    for (Person author : authors) {
      System.out.println(author);
    }
  }
}
    

결과:
Original order:
  A S
  J G
  T C
  C S
  P C
  B B
  Order after sorting using comparator:
  C S
  A S
  J G
  T C
  P C
  B B
  Order after sorting using Comparable method:
  B B
  P C
  T C
  J G
  A S
  C S
    
Comparable인터페이스, 지식인 해결을 하던중, 유저가 만든 인터페이스인줄 알았는데,
자바에서 지원하는 인터페이스다,
객체의 소팅이 필요한경우 자신과 인자로 넘어온 클래스의 값을 비교하여
자신의 순서가 앞에 있어야 한다면 -1, 같다면 0 뒤에 있어야 한다면 1을 리턴하도록 
구현하면된다. 
원시형인경우 소팅하는데 무리가 없지만, 객체인경우 소팅을 하려면 적당한 기준이 있어야한다.
 
Comparable 인터페이스는 객체를 소팅하기위한  기준을 만드는 메소드(compareTo())구현을
요구한다.