아래 블로그 내용에서 다시 보고싶은 내용만 추렸습니다.
더 자세히 알고싶으신 분은 아래 링크로 가는걸 추천드립니다.
Comparable vs Comparator
Comparable은 "자기 자신과 매개변수 객체를 비교" 한다.
compareTo(T o)
Comparator는 "두 매개변수 객체를 비교" 한다.
Compare(T o1, T o2)
Comparable은 자기 자신과 파라미터로 들어오는 객체를 비교하는 것이고, Comparator는 파라미터로 들어오는 두 객체를 비교하는 것이다. 즉, 본직적으로 비교하는 것 자체는 같지만, 비교 대상이 다르다는 것이다.
또 다른 차이점은 Comparable은 lang 패키지에 있기 때문에 import를 해줄 필요가 없지만, Comparator는 util 패키지에 있다.
- Comparable
자기 자신과 매개변수 객체를 비교한다.
public class ClassName implements Comparable<Type> {
// 필수 구현 부분
@Override
public int compareTo(Type o) {
/*
비교 구현
*/
}
}
Example)
class Student implements Comparable<Student> {
int age;
int class;
Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}
@Override
public int compareTo(Student o) {
// 자기자신의 age가 o의 age보다 크다면 양수
if(this.age > o.age) {
return 1;
}
// 자기 자신의 age와 o의 age가 같다면 0
else if(this.age == o.age) {
return 0;
}
// 자기 자신의 age가 o의 age보다 작다면 음수
else {
return -1;
}
}
}
compareTo 메소드는 int 값을 반환해야 하는데, "자기 자신을 기준으로 상대방과 얼마나 차이가 나느냐" 를 기준으로 반환한다.
꼭 1, -1 로 반환하지 않고 양수, 음수로 반환해도 되지만 추천하지 않는다.
두 수의 차를 리턴하는 방법도 있다. 하지만 이 방법을 잘못 사용하면 Underflow(범위의 하한선을 넘어버리는 것) 또는 Overflow(범위의 상한선을 넘어버리는 것) 이 발생할 수 있어 위 코드처럼 < , > , = 로 대소 비교를 하는 것이 일반적이다.
- Comparator
두 매개변수 객체를 비교한다.
import java.util.Comparator; // import 필요
public class ClassName implements Comparator<Type> {
// 필수 구현 부분
@Override
public int compare(Type o1, Type o2) {
/*
비교 구현
*/
}
}
Example)
import java.util.Comparator; // import 필요
class Student implements Comparator<Student> {
int age;
int class;
Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}
@Override
public int compare(Student o1, Student o2) {
// o1의 학급이 o2의 학급보다 크다면 양수
if(o1.classNumber > o2.classNumber) {
return 1;
}
// o1의 학급이 o2의 학급과 같다면 0
else if(o1.classNumber == o2.classNumber) {
return 0;
}
// o1의 학급이 o2의 학급보다 작다면 음수
else {
return -1;
}
}
}
매개변수로 들어오는 두 객체 o1, o2를 비교한다.
a.compare 메소드에서 a와 비교하고 싶다면 아래와 같이 하면 된다.
a.compare(a,b);
Comparator 기능만 따로 두고싶을 때는 익명 객체(클래스)를 활용한다.
익명 객체는 '이름이 정의되지 않은 객체' 를 의미하며
위와 같이 특정 구현 부분만 따로 사용하거나, 부분적으로 기능을 일시적으로 바꾸고 싶을 때 사용한다.
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
// 익명 객체 구현 1
Comparator<Student> comp1 = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.classNumber - o2.classNumber;
}
};
}
// 익명 객체 구현 2
public static Comparator<Student> comp2 = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.classNumber - o2.classNumber;
}
};
}
// 외부에서 익명 객체로 Comparator가 생성되기 때문에 클래스에서 Comparator을 구현 할 필요가 없다.
class Student {
int age;
int class;
Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}
}
위 코드를 보면 외부에서 Comparator를 구현하는 익명객체가 생성되었기 때문에 Student 클래스 내부에서 Comparator를 구현할 필요가 없어졌다.
Example)
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
Student a = new Student(17, 2); // 17살 2반
Student b = new Student(18, 1); // 18살 1반
Student c = new Student(15, 3); // 15살 3반
// comp 익명객체를 통해 b와 c객체를 비교한다.
int res = comp.compare(b, c);
if(res > 0) {
System.out.println("b객체가 c객체보다 크다.");
}
else if(res == 0) {
System.out.println("두 객체의 크기가 같다.");
}
else {
System.out.println("b객체가 c객체보다 작다.");
}
}
public static Comparator<Student> comp = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.classNumber - o2.classNumber;
}
};
}
class Student {
...
}
익명 객체는 이름이 정의되지 않은 하나의 새로운 클래스와 같다.
익명 객체를 가리키는 변수명만 달리하면 몇 개든 자유롭게 생성할 수 있다.
References
'프로그래밍 언어' 카테고리의 다른 글
ArrayList와 LinkedList의 차이 / Stringbuilder (0) | 2022.08.14 |
---|---|
자바 HashMap의 구조 / HashTable / LinkedHashMap (0) | 2022.08.14 |
자바 동기화 | Synchronized(Monitor), Atomic Type (1) | 2022.08.14 |
함수형 프로그래밍이란? 특징? (0) | 2022.08.13 |
[Java] JVM의 구조와 메모리 영역 (0) | 2022.07.28 |
댓글