반응형
오늘은 Comparator 와 Comparable 에 대해 비교하겠다.
위 두 인터페이스는 아래의 생각을 밑바탕으로 사용한다.
"객체를 비교할 수 있도록 만든다."
# 先 정리
Comparable | Comparator | |
오버라이드 메소드 | compareTo(T o) | compare(T o1, T o2) |
비교 대상 | "자기 자신과 매개변수 객체를 비교"하는 것 | "두 매개변수 객체를 비교"하는 것 |
패키지 | 기본(lang에 포함되어있어서 import 필요x) | java.util 에 포함되어있음. |
비교 리턴 | return this.age - o1.age;---- (O) if~else로 return 양수,0,음수아무값 ----(O) |
# Comparable 예제
class Student implements Comparable<Student> {
int age; // 나이
int classNumber; // 학급
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;
}
*/
//아래방식이 제일 간편하다. 양수음수만 아무 값이나 반환하면 상관없다.
return this.age - o.age;
}
}
return this.age - o1.age;
를 사용하는 대신 언더플로우,오버플로우가 되지 않는 int범위 내에서 비교할것 유의!!!
추가로, primitive 값에 대해 위와 같은 예외를 만약 확인하기 어렵다면 <, >, == 으로 대소비교를 해주는 것이 안전하며 일반적으로 권장되는 방식이다.
#Comparator 예제
import java.util.Comparator; // import 필요
class Student implements Comparator<Student> {
int age; // 나이
int classNumber; // 학급
Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}
@Override
public int compare(Student o1, Student o2) {
/*
* 만약 o1의 classNumber가 o2의 classNumber보다 크다면 양수가 반환 될 것이고,
* 같다면 0을, 작다면 음수를 반환할 것이다.
*/
return o1.classNumber - o2.classNumber;
}
}
a.compare(a, b);
를 사용해도 무방하다.
즉, 객체 자체와는 상관 없이 독립적으로 매개변수로 넘겨진 두 객체를 비교하는 것이 포인트다.
Comparable과 마찬가지로 객체간 int값 비교에 오버플로우,언더플로우에 유의해야한다.
Comparator 기능만 따로 두고싶다면 어떻게 해야할까?
답은 매우 간단하다.
"익명 객체(클래스)를 활용한다"
Student를 비교하는 Comparator<Student>를 익명의 객체로 구현해 놓는것.
1,2 번 방식이 있는데 2번 방식이 가독성 측면에서 좋다고 한다.
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 classNumber; // 학급
Student(int age, int classNumber) {
this.age = age;
this.classNumber = classNumber;
}
}
#정렬 활용
Java에서의 정렬은 특별한 정의가 되어있지 않는 한 '오름차순'을 기준으로 한다.
우리가 흔히 쓰는 Arrays.sort(), Collections.sort() 모두 오름차순을 기준으로 정렬이 된다는 것이다.
[두 수의 비교 결과에 따른 작동 방식]
음수일 경우 : 두 원소의 위치를 교환 안함
양수일 경우 : 두 원소의 위치를 교환 함
(설명)
예로들어 {1, 3, 2} 배열이 있다고 가정해보자.
return o1 - o2; 를 한다면, 1-3 = -2로 '음수'가 나올 것이다.
이 때, 자바에서는 오름차순을 디폴트 기준으로 삼고 있다고 했다. 이 말은 선행 원소가 후행 원소보다 '작다'는 뜻이다.
즉, compare 혹은 compareTo를 사용하여 객체를 비교 할 경우 음수가 나오면 두 원소의 위치를 바꾸지 않는다는 것이다.
반응형
'코딩테스트 > Java 문법 정리' 카테고리의 다른 글
int, long 자료형 오버플로우 궁금증해결! (0) | 2022.03.18 |
---|---|
"Comparable VS Comparator" 비교연산 (0) | 2021.05.24 |
[JAVA] "BufferedReader" VS "Scanner" (0) | 2021.05.03 |
Deque(덱, Double-Ended Queue) (0) | 2021.05.03 |
정규표현식 정리(Java,JS,Python 등) (0) | 2021.03.01 |