우보천리 개발

자바 객체 비교, Comparable 그리고 Comparator 본문

언어/Java

자바 객체 비교, Comparable 그리고 Comparator

밥은답 2023. 8. 11. 20:36
반응형

자바에서 기본형에 대해서는 부등호로 크기를 비교할 수 있었다.

하지만 기본형이 아닌 타입에 대해서는 비교를 할 수 있는 기준이 없기 때문에 따로 정의를 해주어야한다.

 

    public static void main(String[] args) {
        int[] scores = {80, 30, 100, 60, 40};
        Arrays.sort(scores);
        System.out.println(Arrays.toString(scores));
    }
    
    // 결과 [30, 40, 60, 80, 100]

 

 

하지만 기본형이 아닌 다른 타입의 객체를 비교하고 싶으면 Comparable 혹은 Comparator 인터페이스를 구현해야한다.

 

1. Comparable

Comparable 인터페이스는 java.lang 패키지에 있다.

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

compareTo 메소드를 오버라이드 해주어야한다.

Comparable 인터페이스는 객체 자기 자신과 매개변수 o로 들어오는 다른 객체를 비교해준다.

 

class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }
}

 

        Student[] students = {
                new Student("김무개", 80),
                new Student("이무개", 100),
                new Student("야무개", 60),
                new Student("된무개", 40),
                new Student("막무개", 30)
        };

        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
        
        // 컴파일 에러

 

Student 객체에는 이름과 점수가 있는데 비교를 해야하는 기준이 정해지지 않았다. 그렇기 때문에 어떠한 기준으로 정렬을 해야되는지 모르기 때문에 컴파일 에러가 발생한다.

 

여기서 Student의 score로 정렬을 하기 위해서 Comparable 인터페이스를 구현하면 된다.

 

class Student implements Comparable<Student> {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public int compareTo(Student other) {
        if (this.score > other.score) return 1;
        else if (this.score < other.score) return -1;
        else return 0;
    }
}

 

자신의 score와 매개변수로 들어온 other의 score을 비교하여 자신이 크면 양수, 작으면 음수, 같다면 0을 반환한다

 

이 부분을 조금 더 간단하게 구현한다고 하면 단순하게 서로의 차이값을 반환하면 된다

    @Override
    public int compareTo(Student other) {
    	return this.score - other.score;
    }
}

이후 실행을 해보면 정렬을 해야하는 기준이 생겼기 때문에 결과가 제대로 나온다

[막무개 30, 된무개 40, 야무개 60, 김무개 80, 이무개 100]

 

2. Comparator

Comparator은 자신과 상관없이 매개변수로 들어오는 두개의 객체에 대해서 비교를 수행한다.

그렇기 때문에 매개변수로 2개의 객체를 받는다.

 

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

 

Comparable과 다르게 Comparator은 객체를 생성해야 compare 메소드를 호출 할 수 있다. 

즉, 비교의 기능만 원하는 상황에서 쓸모없는 객체를 생성해서 비교를 해야하는 번거러운 상황이 나올 수 있다.

 

그렇기 때문에 익명 클래스를 선언하여 사용할 수 있다.

 

Comparator<Student> comp = new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getScore() - o2.getScore();
            }
        };

 

익명 클래스 comp를 만들어서 Student 타입의 객체를 비교하는 Comparator을 만들었다.

 

이를 아까의 예제처럼 정렬을 위해 사용하려면 Arrays.sort()에 인자로 comp를 넘겨주면 된다.

 

        Arrays.sort(students, comp);
        System.out.println(Arrays.toString(students));

 

결과는 위에와 마찬가지로 정렬이 되어서 나올 것이다.

반응형
Comments