본문 바로가기
Programming/JAVA

[Effective java] 객체 순서 비교하기 - compareTo

by 코딩의성지 2023. 2. 4.

오늘은 굉장히 많이 쓰이는 compareTo에 대해 정리해두려 한다.

compareTo는 객체간의 순서를 비교하기 위해 사용된다.

기본적인 동작 방식은 compareTo 는 비교하고자하는 객체보다 작으면 -1을 , 같으면 0을, 크면 1을 반환한다. 만약 비교할 수 없을 경우에는 ClassCastException을 반환하는 것 까지 알아 두자.

 

comareTo 메서드 역시 여느 메서드와 마찬가지로 오버라이딩해서 사용이 가능하다.

하지만 역시나 특정한 조건을 만족해야 된다.

 

이전에 equals 메서드를 정리한 것처럼 , compareTo는 equals와 조건이 비슷하다. 아래

sgn(x.compareTo(y)) == -sgn(y.compareTo(x))
x.compareTo(y) > 0 && y.compareTo(z) > 0 then x.compareTo(z) > 0
x.compareTo(y) == 0 then sgn(x.compareTo(z)) == sgn(y.compareTo(z))
x.compareTo(y) == 0 then x.equals(y) == true // 권고사항은 아니지만 지키면 좋다

 

compareTo는 java7 이후에 나온 메서드인데 이 메서드로 인해 비교 관련한 로직을 짜는데 아주 큰 도움을 많이 줬다. 이전 버전에서는 부등호를 사용하거나 실수형인 경우 compare 메서드를 사용하였다면 이제는 쉽게 compareTo메서드만 활용해서 비교가 가능하다.

Integer num = 10;

if(num.compareTo(20) == 0) {
    ...
}

 

조금더 깊이 있게 정렬 예제를 만들어보겠다.

아래의 User 클래스가 있다. 유저 정보는 이름, 나이, 등급(1.0~5.0)이 존재한다고 가정하자

public class User {
    private String name;
    private int age;
    private double grade;
}

이 클래스를 1순위는 나이로 2순위는 등급으로 3순위는 이름 순으로 정렬한다고 가정하자.

이를 위해서 우리는 compareTo를 직접 구현해줘야한다.

public int compareTo(User user) {
        int result = Integer.compare(age, user.age);
        if(result == 0) {
            result = Double.compare(grade, user.grade);
        }
        if(result == 0) {
            result = name.compareTo(user.name);
        }
        return result;
    }

위와 같이 구현이 될 수 있다. 참고하자. java 8 이상이면 아래와 같은 방식으로 stream을 이용해 조금 더 간결하게 구현이 가능하다. 

private static final Comparator<User> COMPARATOR = Comparator.comparingInt(User::getAge)
        .thenComparingDouble(User::getGrade)
        .thenComparing(user -> user.getName());

public int compareTo(User user) {
    return COMPARATOR.compare(this, user);    
}
반응형

댓글