티스토리 뷰

Comparable 와 Comparator

클래스의 데이터 멤버를 사용해서 객체를 정렬하기 위한 인터페이스

간단한게 표현하면 이렇다.
자바의 기본 자료형들로 Collection이나 Array가 이루어져 있을 경우 기본적인 sort함수 호출로도 정렬이 가능하다.

하지만 우리가 생성한 객체에 대해선 불가능하다.
그 이유는 자바가 비교 기준을 모르기 때문이다.
우리가 만든 클래스에 대해 비교 기준을 알지 못하므로 우리는 비교 기준을 정의해야된다.

Comparable과 Comparator는 비교 기준을 정의한 것


Comparator

객체 정렬기준을 외부에서 지정한 것

주로 하나의 객체를 여러가지 기준으로 정렬할 때 사용된다.
util패키지에 존재하므로 Import해줘야된다.

Comparable

객체 자기 자신이 정렬 기준을 가진 것

자기자신 obj와 다른 obj를 비교할 때 사용된다.
자바의 기본 패키지인 Lang패키지에 존재하므로 Import가 필요없다.


간단한 성능 이야기

기본적으로 둘은 비교 기준을 정의한 것이므로 시간복잡도는 구현한 자료구조에 따라서 달라진다.
예를 들어서 우선순위 큐를 가지고 구현했으면 N개에 대하여 N log N을 가지게 되는 것.

그 이외의 둘의 차이는 객체 생성 여부 이다.

Comparable은 객체를 생성하지 않고 자기 자신이 가지고 있기에 객체 생성의 Overhead가 들지 않는다.
Comparator는 객체를 생성하여 외부에서 지정하는 것이여서 Overhead가 발생한다.

하지만 Comparator를 익명클래스로 static하게 정의하면 프로그램 실행시
JVM의 메모리 공간 Method area에 올라가 객체 생성 OverHead가 없다.

따라서 성능 부분은 또이또이 한것

주의점

둘다 method를 override해서 사용하는 데, 둘 메소드 동일하게 int형을 반환한다.
여기서 -1,0,1 3가지 값을 반환하는 데, 단순하게 두 값을 - 연산을 통해 반환하면 아시다시피 OverFlow 가 발생하여 문제가 된다.
Int값의 Max와 그것의 Int 값의 Min을 뺄셈했다고 가정하면, Max 값을 넘어가므로 OverFlow 가 발생할 것이다.

조건문으로 비교후 -1,0,1을 리턴하거나, Integer.compare() 같은 함수를 사용하자!

왜 -1,0,1 일까?

자바는 비교 연산시 자연스러운 순서,즉 오름 차순이 기본이다.
그러므로 예를 들어서 1과 3을 비교한다고 가정하면, 1 - 3 => -2 , -2 라는 값이 return 되고
음수는 이미 오름차순 정렬이 되있구나라고 판단하여 두 값의 교환이 일어나지 않는다.
3과 1일 경우, 3 - 1 => 2 라는 양수가 return
양수는 오름차순 정렬이 아니므로 두 값의 교환이 발생.

  • 음수 : 현재 객체가 앞으로 온다.
  • 양수 : 현재 객체가 뒤로간다.

이렇게 알면 편하다.


구현

일부러 오름 차순 말고 내림 차순으로 구현했다.
오름차순과 내림차순은 단순히 두 파라미터의 순서만 바꿔주면 끝이다.

Comparator


package com.example;
import java.util.*;

class Node {
    int dest,cost;
    public Node (int dest,int cost){
        this.dest = dest;
        this.cost = cost;
    }
}
public class Main {
    static Comparator<Node> comp = (a,b) -> {
        if (a.cost > b.cost){
            return -1;
        }
        else {
            return 1;
        }
    };
    public static void main(String[] args){
        List<Node> nodes = new ArrayList<>();
        nodes.add(new Node(1,1));
        nodes.add(new Node(3,3));
        nodes.add(new Node(4,4));
        nodes.add(new Node(2,2));


        Collections.sort(nodes,comp);
        for (Node n : nodes){
            System.out.println(n.dest + " : "+n.cost);
        }
    }

}

Comparable


package com.example;
import java.util.*;

class Node implements Comparable<Node>{
    int dest,cost;
    public Node (int dest,int cost){
        this.dest = dest;
        this.cost = cost;
    }

    @Override
    public int compareTo(Node other){
        return Integer.compare(other.cost,this.cost);
    }
}
public class Main {

    public static void main(String[] args){
        List<Node> nodes = new ArrayList<>();
        nodes.add(new Node(1,1));
        nodes.add(new Node(3,3));
        nodes.add(new Node(4,4));
        nodes.add(new Node(2,2));


        Collections.sort(nodes);
        for (Node n : nodes){
            System.out.println(n.dest + " : "+n.cost);
        }
    }

}

혹시 틀린 점이나 궁금한 점 있으면 댓글 달아주시면 감사하겠습니다 ^^

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함