지식조각모음
Comparator와 Comparable 본문
11장을 읽다가 이 부분만 따로 정리하고 싶어서 새 글을 작성했다.
1. Comparator와 Comparable 소개
먼저 Comparator와 Comparable 모두 인터페이스이다. 둘 다 컬렉션 정렬에 필요한 메소드를 정의해 놓았다는 공통점이 있다.
Interface Comparator<T>Interface Comparable<T>
그러면 왜 이런 인터페이스가 필요할까? 먼저 기본 자료형(primitive type)은 부등호로 비교가 가능하다.
int a = 1;
int b = 2;
if (a == b) {
return true;
} else {
return false;
}하지만 그 외 클래스는 어떻게 비교할 수 있을까?
2. 왜 사용할까?
public class Test {
public static void main(String[] args) {
Student a = new Student();
Student b = new Student();
// a와 b비교????
}
}
class Student {
private int studentNumber;
private int age;
private String name;
// getter, setter 생략
}Student a와 Student b를 비교하려고 할 때
- 어떤 기준으로 비교할 것인가
- 기준이 되는 값을 어떤 방식으로 비교할 것인가
를 고려하여 매번 비교 메서드를 작성해야 한다. 아래 예시처럼 기준을 매번 정해야하고 매번 새로 정의해줘야 한다.
public class Test {
public static void main(String[] args) {
Student a = new Student();
Student b = new Student();
// a와 b비교 1
// studentNumber를 기준
if (a.studentNumber > b.studentNumber) {
// a > b
} else if (a.studentNumber < b.studentNumber) {
// a < b
} else { // a.studentNumber == b.studentNumber
// a == b
}
// a와 b비교 2
// age 기준
if (a.age > b.age) {
// a > b
} else if (a.age < b.age) {
// a < b
} else { // a.age == b.age
// a == b
}
}
}
public class Student {
private int studentNumber;
private int age;
private String name;
// getter, setter 생략
// 또는
public boolean compareTo(Student student) {
// studentNumber를 기준
if (this.studentNumber > student.studentNumber) {
// this > student
} else if (this.studentNumber < student.studentNumber) {
// this < student
} else { // this.studentNumber == student.studentNumber
// this == student
}
}
}그러다보면 compareTo(), compare(), comparetWith() 처럼 같은 기능을 다양하게 각자 생각한 방식대로 구현할 것이고 그 기준과 구현방식이 중구난방일 것이다. 이런 문제점을 해결하기 위해 Comparable 또는 Comparator를 사용한다.(getter와 setter처럼 이해했다)
3. Comparator와 Comparable의 차이점
- Comparable은 기본 정렬 기준을 구현하는데 사용하면 객체 자신(this)과 파라미터로 받은 객체를 비교한다.
public interface Comparable {
int compareTo(Object o);
}- Comparator은 기본 정렬기준 외에 다른 기준으로 정렬하고자 할 때 사용한다.
public interface Comparator {
int compare(Object o1, Object o2);
boolean equals(Object obj);
}4. Comparable
Comparable 인터페이스가 어떻게 정의되어 있는지 확인해보면,
public interface Comparable<T> {
public int compareTo(T o);
}
주석을 제외하면 메소드 하나만 가지고 있고 제네릭 타입을 받는다. compareTo()는 비교하고자 하는 Object를 파라미터로 받는다. 반환 타입을 보면 int로 되어 있는데 자기 자신과 파라미터로 받은 object를 비교결과를 int로 반환한다.
- 자기 자신이 더 작으면 -1 (negative integer)
- 동일하면 0
- 자기 자신이 더 크면 1 (positive integer)
이렇듯 Comparable을 사용해서 객체를 비교하려고 하면 기본적으로 Comparable 인터페이스를 상속받아야 한다. 이때 CompareTo() 을 반드시 구현해야 한다. 위의 Student 클래스를 Comparable를 사용해서 구현해보면 이렇다.
public class Student implements Comparable<Student> {
private int studentNumber;
private int age;
private String name;
public Student(int studentNumber, int age, String name) {
this.studentNumber = studentNumber;
this.age = age;
this.name = name;
}
@Override
public int compareTo(Student student) {
if (this.studentNumber > student.studentNumber) {
return 1;
} else if (this.studentNumber == student.studentNumber) {
return 0;
} else {
return -1;
}
// 위 코드는 아래처럼 간단하게 바꿀수 있다.
// return this.studentNumber - student.studentNumber;
}
}
정리하면 Comparable를 사용하면 객체를 비교할 수 있다.
이 때, compareTo() 메소드를 반드시 구현해야 하며,
반환값은 자기 자신을 기준으로 비교 대상과의 차이 값을 intger로 반환한다.
Comparator
'책 > 자바의 정석' 카테고리의 다른 글
| 13. 스레드 (2) | 2022.03.30 |
|---|---|
| 12. 제네릭스, 열거형, 애너테이션 (0) | 2022.03.13 |
| 11. 컬렉션 프레임웍 (0) | 2022.03.06 |
| 10. 날짜와 시간 & 형식화 (1) | 2022.03.05 |
| 9. java.lang 패키지와 유용한 클래스 (0) | 2022.03.03 |