목차
반응형

Comparable <T> 인터페이스
`Comparable` 인터페이스는 `Comparator` 와 함께 정렬 규칙을 재정의해 객체 정렬을 가능하게 합니다.
`Arrays.sort()`과 같이 java에서 기본으로 제공하는 static 메서드로는 객체를 정렬할 수 없습니다.
Comparable vs Comparator
- `Comparable` : 결과값인 정수값에 따라 객체를 대상으로 기본 정렬 기준을 정의하는 데 사용(오름차순, 내림차순 등)
- `Comparator` : 기본 정렬 값 제외한 다른 기준을 정의할 때 사용
Comparable을 활용한 Collections.sort 메소드 호출의 이해

java
닫기public static <T extends Comparable<? super T>> void sort(List<T> list)
java api 공식 문서에 나와있는 `Collections.sort` 의 정의 부분을 참고하면 아래와 같이 구현되어야 함을 알 수 있습니다.
- `sort` 의 입력 인자값은 `List`여야 한다
- `T extends Comparable<T>` : 인자값의 타입은 `Comparable <T>` 인터페이스를 상속(구현) 해야 한다
이어서 Comparable<T> 인터페이스의 구성요소를 살펴보겠습니다.

Comparable <T> 인터페이스는 `int compareTo(T o)` 메서드 한 개로만 구성되어 있습니다.
따라서 알 수 있는 점은 아래 두 가지 입니다.
- `Collections.sort` 메서드의 정렬 방식을 재정의하는 메서드가 바로 `compareTo(T o)`이다
- `compareTo(T o)` 메서드만 구현하면 Comparable 인터페이스를 구현한 클래스 타입의 리스트를 인자값으로 넘겨 `Collections.sort`를 사용할 수 있다.
Comparable <T> 인터페이스를 구현하는 클래스를 정의하는 예제와 함께 설명하겠습니다.
구현
Comparable을 구현하는 클래스
Q. 구현 예제 목표
2차원 지표인 x 값, y 값을 나타내는 정수값들이 순차적으로 주어지면,
x 값을 기준으로 우선적으로 정렬하고, 후순위로 y 값을 기준으로 정렬하는 메서드 sort를 구현한다.
EX) `(4, 1), (1, 3), (1, 2), (3, 3)` → `(1, 2), (1, 3), (3, 3), (4, 1)`
implement Comparable <T>, 메서드 compareTo 구현
아래 방식은 여러 유형의 변수를 우선순위를 부여하여 정렬하는 구현 과제에서 자주 사용되는 방식입니다.
java
닫기class Pos implements Comparable<Pos> { int x; int y; Pos(int x, int y) { this.x = x; this.y = y; } @Override public int compareTo(Pos p) { // 우선순위인 x를 기준으로 비교 후 y를 비교한다. if (this.x == p.x) return this.y - p.y; // x가 동일할 때 y값을 비교한다. // this.y > p.y인 경우 양의 정수, this가 더 크며, p가 더 작다 // this.y == p.y인 경우 0 : this와 p의 값이 동일하다 // this.y < p.y인 경우 음의 정수, this가 더 작으며, p가 더 크다 else return this.x - p.x; // x값을 비교한다. } }
- 인자값으로 입력받을 x 좌표, y 좌표를 하나의 객체로 정의할 클래스를 선언합니다.
- `Collections.sort` 메서드, List의 인자값으로 해당 클래스를 집어넣기 위해서 `Comparable <클래스>`를 구현합니다.
- 생성자를 통해 입력되는 x, y 값을 객체의 필드로 선언합니다.
- 정렬 규칙을 정의한 compareTo 메서드를 정의합니다.
- `compareTo`(클래스 인스턴스) : 현재의 객체와 인자값의 객체를 비교합니다.
- return 하는 int 값이 음수 / 양수 / 0 인지를 기준으로 인스턴스 값 간의 크고 작음의 비교 기준을 정의합니다.
- 음수 : 인자값으로 받은 객체가 더 크다
- 0 : 현 객체와 인자값으로 받은 객체 값이 동일하다
- 양수: 인자값으로 받은 객체가 더 작다
- `compareTo`를 구현 후 `Collections.sort` 사용 시 해당 기준에 맞춰 오름차순으로 정렬합니다.
- (클래스가 규정하는 작은 값 → 큰 값 순)
main(정렬 구현 확인)
java
닫기class ComparableSort { public static void main(String[] args) { ArrayList<Pos> list = new ArrayList<>(); list.add(new Pos(4, 1)); list.add(new Pos(1, 3)); list.add(new Pos(1, 2)); list.add(new Pos(3, 3)); System.out.println(list.get(0).compareTo(list.get(1))); // out : 3 (index 0이 index 1보다 크다) System.out.println(list.get(1).compareTo(list.get(2))); // out : 1 (index 1이 index 2보다 크다) System.out.println(list.get(2).compareTo(list.get(3))); // out : -2 (index 2가 index 3보다 작다) // compareTo 정의 기반 정렬 확인 (작은 값 -> 큰 값의 오름차순) Collections.sort(list); for (Pos p : list) System.out.println(p.x+ " "+p.y); // out // 1 2 // 1 3 // 3 3 // 4 1 }
위의 예시를 보면 의도한 대로 x값이 우선적으로 오름차순 정렬되고, 후순위로 y값이 정렬됨을 확인할 수 있습니다.
compareTo를 변경함에 따라 y값 우선정렬, 내림차순 정렬 등도 가능합니다.
1. 내림차순 정렬(우선순위 x > y)
java
닫기class Pos implements Comparable<Pos> { // .. 생략 .. @Override // y값 우선 정렬 public int compareTo(Pos p) { if (this.x == p.x) return p.y - this.y; else return p.x - this.x; } } // .. 생략 .. public static void main(String[] args) { ArrayList<Pos> list = new ArrayList<>(); list.add(new Pos(4, 1)); list.add(new Pos(1, 3)); list.add(new Pos(1, 2)); list.add(new Pos(3, 3)); Collections.sort(list); for (Pos p : list) System.out.println(p.x+ " "+p.y); // out // 4 1 // 3 3 // 1 3 // 1 2 }
2. 오름차순 정렬(우선순위 y > x)
java
닫기class Pos implements Comparable<Pos> { // .. 생략 .. @Override // y값 우선 정렬 public int compareTo(Pos p) { if (this.y == p.y) return this.x - p.x; else return this.y - p.y; } } // .. 예시 결과 출력 생략 ..
여기까지 Comparable을 활용한 Collections.sort 정의를 알아봤습니다.
다음 시간에는 Comparator를 들고 오겠습니다.
# 구현 코드
반응형
'DEV > Java' 카테고리의 다른 글
[java] 스트림 도전기 (2 / 3) - 람다식, java.util.function (2) | 2023.10.18 |
---|---|
[java] 어노테이션(Annotation)의 이해와 사용방법 (2) | 2023.10.17 |
[java] 중첩 클래스(Nested Class)의 이해와 구현 (1) | 2023.10.09 |
[java] 코딩테스트 대비 java 클래스 별 메소드 정리 (2 / 2) (0) | 2023.10.05 |
[java 기초] 기타 제어자(static, final, abstract)의 이해와 구현 (0) | 2023.10.05 |