Comparator / Comparable 이 뭐야?

Loopy·2024년 1월 7일
0

자료구조

목록 보기
3/4


✅ Comparator와 Comparable

두가지 모두 두개의 객체를 비교하기 위한 인터페이스 이다.

Comparator의 compare() 메서드는 두 매개변수 객체를 비교하고,

Comparable의 compareTo() 메서드는 자기자신과 매개변수 객체를 비교한다.

객체 o1, o2가 있을 때, compare(o1, o2) / o1.compareTo(o2) 가 가능할 것이다.

이때, return 값에 따라 o1과 o2의 위치가 결정된다.

return 1 (양수) : 위치를 변경하지 않음. 즉, o1이 o2보다 앞쪽에 위치하도록 결정
return -1(음수) : 위치를 변경함. 즉, o1이 o2의 뒤에 위치하도록 결정
return 0 : return1과 비슷하거나 같음. 위치를 변경하지 않음

public interface Comparator<T> {
	int compare(T o1, T o2);
}

public interface Comparable<T> {
	public int compareTo(T o);
}

✅ Comparator 구현

MyMember라는 객체를 정렬하고자 할때, 정렬 조건을 설정하기위해 Comparator 클래스를 구현한다.

o1의 나이 > o2의 나이 인 경우 - return 1 : o1이 o2의 앞쪽에 위치. 즉 o1 - o2 순서.
o1의 나이 == o2의 나이 인 경우 - return 0 : 순서를 변경하지 않음. 즉 list에 추가된 순서대로 위치.
o1의 나이 < o2의 나이 인 경우 - return -1 : 순서를 변경하여 o2가 o1보다 앞쪽에 위치하도록 변경. 즉 o2 - o1 순서.

Collections.sort(list, new Comparator<MyMember>() {
            @Override
            public int compare(MyMember o1, MyMember o2) {
                if(o1.age>o2.age)return 1;
                else if(o1.age==o2.age)return 0;
                else return -1;
            }
});

람다식 사용 (Comparator)

아래 두개의 결과는 같다.

Collections.sort(list, (o1, o2) -> {
            if(o1.age>o2.age)return 1;
            else if(o1.age==o2.age)return 0;
            else return -1;
});
Collections.sort(list, (o1, o2) -> {
           	return o1.age-o2.age;
});

✅ 예제

정렬 예제 1. Comparator 사용

Comparator로 정렬 방법을 설정할 수 있다.
아래 예제의 경우에는 age, memberId 중 age가 작은 순서대로 정렬하였다.

o1, o2가 주어졌을 때, compare(o1, o2)의 return에 따라 크기(순위)가 결정된다.
return 1 : o1이 더 크다는 뜻 이므로, 정렬 시 o1이 o2의 뒤에 위치하게 된다.
return -1 : o2가 더 크다는 뜻 이므로, 정렬 시 o2가 o1의 뒤에 위치하게 된다.

class MyMember{
    String name;
    int age;
    int memberId;

    public MyMember(String name, int age, int memberId) {
        this.name = name;
        this.age = age;
        this.memberId = memberId;
    }
}
public class Test{
    public static void main(String[] args){
        MyMember memberA = new MyMember("memberA",30,1001);
        MyMember memberB = new MyMember("memberB",15,1010);
        MyMember memberC = new MyMember("memberC",20,1005);

        List<MyMember> list = new ArrayList<>();
        list.add(memberA);
        list.add(memberB);
        list.add(memberC);

        Collections.sort(list, new Comparator<MyMember>() {
            @Override
            public int compare(MyMember o1, MyMember o2) {
                if(o1.age>o2.age)return 1;
                else if(o1.age==o2.age)return 0;
                else return -1;
            }
        });
        System.out.println(list.get(0).name+" "+list.get(1).name+" "+list.get(2).name);
	// memberB memberC memberA
    }
}

만약 age가 큰 순서대로 정렬하고 싶다면, compare() 부분을 아래와 같이 변경하면 된다.

Collections.sort(list, new Comparator<MyMember>() {
           @Override
           public int compare(MyMember o1, MyMember o2) {
               if(o2.age>o1.age)return 1;
               else if(o1.age==o2.age)return 0;
               else return -1;
           }
});

정렬 예제 2. Comparable 사용

이번엔 정렬 대상이 되는 클래스에 직접 implements Comparable<>를 적용해보자.
이 경우에는 main에서 Collections.sort(list)를 했을 때, MyMember클래스 내부에서 이미 적용된 정렬 방식에 따라 정렬된다.

class MyMember implements Comparable<MyMember>{
    String name;
    int age;
    int memberId = 1000;

    public MyMember(String name, int age, int memberId) {
        this.name = name;
        this.age = age;
        this.memberId = memberId;
    }

    @Override
    public int compareTo(MyMember o) {
        if(this.age>o.age)return 1;
        else if(this.age==o.age)return 0;
        else return -1;
    }
}
public class Test{
    public static void main(String[] args){
        MyMember memberA = new MyMember("memberA",30,1001);
        MyMember memberB = new MyMember("memberB",15,1010);
        MyMember memberC = new MyMember("memberC",20,1005);

        List<MyMember> list = new ArrayList<>();
        list.add(memberA);
        list.add(memberB);
        list.add(memberC);

        Collections.sort(list);
        System.out.println(list.get(0).name+" "+list.get(1).name+" "+list.get(2).name);
	// memberB memberC memberA

    }
}
profile
잔망루피의 알쓸코딩

0개의 댓글