JAVA & Spring

[JAVA] Comparator / Comparable - 정렬을 위한 클래스(인터페이스)

HSRyuuu 2023. 6. 10. 23:15

Comparator와 Comparable

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

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

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

 

객체 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 순서.

위에서 설명했듯이 꼭 1, -1이 아니고 양수, 음수이면 되기 때문에 if,else if, else 문 대신에 ' return o1-o2; ' 를 해도 된다.

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에 따라 크기(순위)가 결정된다.
  1. return 1 : o1이 더 크다는 뜻 이므로, 정렬 시 o1이 o2의 뒤에 위치하게 된다.
  2. 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

    }
}
반응형