객체비교
우리는 자바에서 지원되는 메서드나 혹은 자료구조를 통해서 이미 primitive 변수들을 정렬하는 방법에 대해서는 잘 알고 있다.
하지만 객체 즉, 클래스 안에 변수들을 매개로 정렬하는 방법에는 잘 모르는 경우가 있다.
이를 자바에서는 Comparable과 Comparator를 사용하여 정렬한다. 이에 대해서 공부해보자.
public interface Comparator<T> {
int compare(T o1, T o2);
}
public interface Comparable<T> {
public int compareTo(T o);
}
Comparable과 Comparator
Comparable은 "자기 자신과 매개변수 객체를 비교"하는 것이고, Comparator는 "두 매개변수 객체를 비교"한다는 것이다.
Comparable은 자기 자신과 파라미터로 들어오는 객체를 비교하는 것이고, Comparator는 자기 자신의 상태가 어떻던 상관없이 파라미터로 들어오는 두 객체를 비교하는 것이다. 즉, 본질적으로 비교한다는 것 자체는 같지만, 비교 대상이 다르다는 것이다.
또한 다른 차이점이라면 Comparable은 lang패키지에 있기 때문에 import 를 해줄 필요가 없지만, Comparator는 util패키지에 있다.
그렇다면 좀 더 깊게 공부해보자.
Comparable
위 사진은 Comparable의 정의이다. interface로 되어있는데
가장 중요한 부분은 아래에 있는 바로 compareTo 부분이다.
예를 들어
쉽게 생각하면 이렇다. 여러분이 클래스를 만들 때, 클래스 내부에 변수를 비교하고 싶을 것이다.
아까 Comparable은 자기 자신과 매개변수 객체를 비교한다고 했다. 즉, 자기자신은 x로 생성한 객체 자신이 되고, 매개변수 객체는x.compareTo(o); 를 통해 들어온 파라미터 o가 비교 할 객체가 되는 것이다.
class Pair implements Comparable<Pair>{
int x;
int y;
Pair(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(@NotNull Pair o) {
return 0;
}
}
이제 compareTo 메소드를 구현해야 할 것이다. 만약 x를 기준으로 비교(대소 관계)를 하고자 한다면 어떻게 하면 될까?
자기 자신의 x와 매개변수로 들어온 o의 x의 값을 비교하면 된다.
class Pair implements Comparable<Pair> {
int x;
int y;
Pair(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(@NotNull Pair o) {
if (this.x > o.x) {
return 1;
} else if (this.x == o.x) {
return 0;
} else {
return -1;
}
}
}
자기 자신과 상대방을 비교하여 양수,0,음수를 반환하는 것이다.
이를 통해서 상대방이 나보다 크거나 작거나 같음을 알고, 객체비교를 실행할 수 있다.
Comparator
Comparator는 Comparable과 달리 두 매개 변수 객체를 비교한다.
이 말은 Comparable과 달리 자기 자신이 아니라 파라미터로 들어오는 두 객체를 비교하는 것이다.
class Pair implements Comparator<Pair> {
int x;
int y;
Pair(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compare(Pair o1, Pair o2) {
return 0;
}
}
compare() 메소드가 바로 우리가 객체를 비교할 기준을 정의해주는 부분이 된다.
기본적으로 원리는 compareTo와 같으나 단순히, 자기 자신과 비교되느냐 안되느냐가 차이이다.
위 Pair Class로 또 구현해보자.
class Pair implements Comparator<Pair> {
int x;
int y;
Pair(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compare(Pair o1, Pair o2) {
if (o1.x > o2.x) {
return 1;
} else if (o1.x == o2.x) {
return 0;
} else {
return -1;
}
}
}
앞서 Comparable의 compareTo()와는 다르게, 두 객체를 비교하는 것이기 때문에 파라미터로 들어오는 o1과 o2의 x을 비교해주는 것이다.
좀 더 구체적으로 말하자면 Comparable의 compareTo는 선행 원소가 자기 자신이 되고, 후행 원소가 매개 변수로 들어오는 o 가 되는 반면에, Comparator의 compare는 선행 원소가 o1이 되고, 후행 원소가 o2가 된다.
객체 정렬
앞서 이러한 것들은 객체를 정렬하기 위함이라고 하였다.
그렇다면 Java에서 사용할 수 있는 Collections.sort를 이용하여 객체를 정렬해보자.
Comparable의 경우
만약 위 Pair클래스 처럼 Comparable를 구현하여 만들었다면 Collections.sort()를 사용하여 리스트를 정렬하면 끝이다.
class Pair implements Comparable<Pair> {
int x;
int y;
Pair(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(@NotNull Pair o) {
if (this.x > o.x) {
return 1;
} else if (this.x == o.x) {
return 0;
} else {
return -1;
}
}
}
Collections.sort(arr);
Comparator의 경우
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
numArr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(numArr);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
arr.add(new Pair(numArr[i], numArr[j]));
}
}
arr.sort((o1, o2) -> {
if (o1.x < o2.y) {
return 1;
} else if (o1.x == o2.y) {
return Integer.compare(o2.y, o1.y);
} else {
return -1;
}
});
위 코드를 보시다시피 Comparator에서는 익명 클래스를 사용하여 정렬 할 수 있다.
참고
https://dding9code.tistory.com/68
'Programming Language > Java' 카테고리의 다른 글
[Java] String, StringBuffer, StringBuilder에 대해서 정리하자 (0) | 2024.06.01 |
---|---|
[Java] 변수(Variable) (0) | 2024.01.04 |
[Java] synchronized는 자바 몇 버전 부터 사용된 걸까? (0) | 2023.09.10 |
[Java] JVM (Java Virtual Machine) 자바 가상 기계 (0) | 2023.07.27 |
[Java] Garbage Collection(가비지 컬렉션)이란 (0) | 2023.04.19 |