빰_s
(25.01.26) Comparator VS Comparable 본문
자바 사용 중 배열 정렬을 위해 Arrays.sort()를 사용해본 경험이 있을 것이다.
이 메소드는 기본적으로 배열을 크기 기준 오름차순으로 정렬해주는 기능을 가지는데, 때로는 그 역으로 정렬하고 싶거나 자기가 직접 정한 기준으로 정렬을 하고 싶어질 때도 있을 수도 있다.
이러한 정렬 로직을 구축할 수 있는 자바의 기능이 제목에 언급된 Comparator와 Comparable라는 인터페이스가 있다.
오늘은 이 두가지 인터페이스를 비교해보도록 하자.
1. Comparable
정렬 수행 시 기본적으로 적용되는 정렬 기준이 되는 메소드를 정의하는 인터페이스다.
// Integer class
public final class Integer extends Number implements Comparable<Integer> { ... }
// String class
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { ... }
// 출처 : https://gmlwjd9405.github.io/2018/09/06/java-comparable-and-comparator.html
자바에서 제공되는 정렬이 가능한 모든 클래스들은 Comparable 인터페이스를 사용하고 있으며, 정렬 시에 이에 맞게
정렬이 수행된다.
※ 구현 방법
// x좌표가 증가하는 순, x좌표가 같으면 y좌표가 감소하는 순으로 정렬 진행
class Point implements Comparable<Point> {
int x,y;
@Override
public int compareTo(Point p) {
if(this.x > p.x) {
return 1;// x에 대해선 오름차순
}
else if(this.x == p.x) {
if(this.y < p.y) {
return 1; // y에 대해선 내림차순
}
}
return -1;
}
}
//main에서의 사용법
List<Point> pointList = new ArrayList<>();
pointList.add(new Point(x,y));
Collections.sort(pointList);
Comparable 인터페이스를 Implement 할 시, 자동으로 @Override로써 주어지는 CompareTo() 메서드를 이용하여 정렬 기능을 구현한다.
즉 CompareTo를 통해 정렬 로직을 커스텀할 수 있고, Collectionms.sort() 등을 사용해서 이를 정렬할 수 있다.
CompareTo(T o)를 작성 시 유념해야 할 것은 다음과 같다.
- 하나의 매개변수에는 정렬을 진행할 대상 객체가 들어가며, Collections.sort나 Arrays.sort가 진행된 배열 객체는 CompareTo(T o)의 로직을 따른다.
- 리턴 값이 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우엔 두 객체의 자리가 바뀐다.
( 현재 각체 < 파라미터로 넘어온 객체 : 음수 리턴)(※ 기본적으로 오름차순 정렬이므로 아무런 변화가 일어나지 않는다.)
( 현재 겍체 == 파라미터로 넘어온 객체 : 0 리턴)
( 현재 객체 > 파라미터로 넘어온 객체 : 앙수 리턴) (※ 두 객체의 비교 결과가 양수면 두 객체의 위치를 바꾸는 식으로 정렬이 가능하다.)
2. Comparator : 정렬 가능한 클래스( == Comparable 인터페이스를 구현한 클래스)들의 기본 정렬 기준과 또 다르게 정렬하고 싶을 때 사용하는 인터페이스
Comparable 인터페이스는 CompareTo(T o), 매개변수를 대상 객체 자체만 받는 정렬 로직을 사용하는데, Comparator는
Compare(T o1, T o2)의 구조를 가진다. 이는 o1과 o2 이 두 객체의 크기를 비교해서 정렬을 수행한다는 의미가 되며, 여기서 Comparator와 Comparable의 차이가 발생한다.
그럼 이번엔 Comparator의 사용법을 알아보자.
//좌표가 증가하는 순, x좌표가 같으면 y좌표가 감소하는 순으로 정렬하라.
class MyComparator implements Comparator<Point> {
@Override
public int compare(Point p1, Point p2) {
if(p1.x > p2.x) {
return 1; // x에 대해선 오름차순
}
else if(p1.x == p2.x) {
if(p1.y < p2.y) {
return 1; //y에 대해선 내림차순
}
}
return -1;
}
}
//Main에서의 사용법
List<Point> pointList = new ArrayList<>();
pointList.add(new Point(x,y));
MyComparator myComparator = new MyComparator();
Collections.sort(pointList, myComparator);
//Arrays.sort(), Collections.sort() 메서드는 두번째 인자로 Comparator interface를 받을 수 있다.
- 리턴되는 객체가 음수 또는 0이면 객체의 자리가 그대로 유지되며, 양수인 경우엔 두 객체의 자리가 변경된다.
- 첫번째 파라미터가 o1, 두번째 파라미터가 o2라 했을 때
-- o1 < o2 : 음수 리턴
-- o1 == o2 : 0 리턴
-- o1 > o2 : 양수 리턴(정렬 개선 변경 발생)
이 두 인터페이스를 이용해 우선순위 큐의 정렬 기준을 변경하거나, 자기 희망사항 대로 정렬을 진행하는 등의 업무가 가능할 것이다.
'Java' 카테고리의 다른 글
(25.02.16) 힙, 우선순위 큐의 개념과 사용 (0) | 2025.02.16 |
---|---|
(25.01.05) Array vs ArrayList vs LinkedList (0) | 2025.01.05 |
[Java] 소숫점 자릿수만큼 출력하는 방법 (0) | 2024.01.01 |
(2023.02.02) 객체지향 설계 원칙(S O L I D) (0) | 2023.02.02 |
(22.07.27) String vs StringBuffer vs StringBuilder (2) | 2022.07.27 |