Study-Standard-Of-Java / community

커뮤니티
0 stars 0 forks source link

[11장] Comparable, Comparator의 차이? #17

Closed choigy1001 closed 2 years ago

choigy1001 commented 2 years ago

비교하는 메서드를 구현한다는 의미는 같습니다. 하지만 어떤 상황에 더 적합한지를 알면 조금 더 쉽게 사용할 수 있을거 같습니다. 저 또한 정리해서 여기에 올려두겠습니다!

choigy1001 commented 2 years ago

제가 봤던 내용과 코드 실습을 토대로 해보면 설명을 드리자면

public class FirstClass implements Comparable<FirstClass>, Comparator<FirstClass> {

    private String name;
    private int age;

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

    public FirstClass() {
    }

    @Override
    public int compareTo(FirstClass o) {
        return this.age - o.age;
        // 나이 대신 사용할 경우 오버, 언더 플로우 조심!
    }

    public static void main(String[] args) {
        FirstClass one = new FirstClass("gyoung", 25);
        FirstClass two = new FirstClass("giii", 24);
        FirstClass three = new FirstClass("yoo", 28);
        int i = one.compareTo(two);
        if (i > 0) {
            System.out.println("one이 더 큼");
        } else if (i == 0) {
            System.out.println("같다");
        } else {
            System.out.println("one이 더작다");
        }
        int compare = one.compare(two, three);
    }

    @Override
    public int compare(FirstClass o1, FirstClass o2) {
        return o1.age - o2.age;
    }
}

다음과 같이 Comparable, Comparator를 구현하는 것은 비교를 위한 일입니다. 단순하게 보면 comparable은 생성된 객체와 다른 객체를 비교하는 연산을 하고 있습니다. one.compareTo(two);

Comparator를 구현할때는 compareTo 메서드를 재정의하는데 다음과 같이 연산을 합니다. int compare = one.compare(two, three);

비교하는 대상이 다르다는 것을 확인할 수 있을 겁니다. compareTo는 one과 two를, compare는 two와 three를 비교하고 있습니다.

그렇기에 API를 사용하는 관점에서 보면 Arrays.sort(list, new Comparator를 구현한 클래스명()); 이렇게 Comparator를 구현한 클래스 객체를 사용하는 일이 자주 있는데 물론 sort의 매개변수가 Comparator를 받는것도 있지만 그 내부의 구현을 보면 Comparable로 형변환하여 compareTo를 사용하고 있습니다.

본질적으로 다시 생각해보면 두 인터페이스 모두 객체의 비교 기준을 세우기 위해 만들어졌다는게 핵심이라고 생각합니다. 큰 차이점은 비교하는 대상이 다르다이겠네요.

결론적으로 두 인터페이스를 구현하여 사용하는 시기는 (무적의 문장 같아서 죄송하지만) 상황에 맞게 사용하는 것이 적절하다는게 제 결론이네요.

kiiiyeon commented 2 years ago

Common

Difference

Comparator

Comparable

사용 예시 - 백준 1181번

1) String의 길이를 비교하여 오름차순으로 정렬하는 함수

길이가 같을 경우, 사전순 정렬 (2번에서 부연 설명)

Arrays.sort(strings, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if (o1.length() == o2.length()) {
                    return o1.compareTo(o2);
                }

                return o1.length() - o2.length();
            }
        });

내림차순 정렬의 경우

객체를 비교하는 순서를 변경

Arrays.sort(strings, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if (o1.length() == o2.length()) {
                    return o2.compareTo(o1);
                }

                return o2.length() - o1.length();
            }
        });

2) 비교 대상에 문자열이 포함된 경우

compareTo()로 스트링을 비교할 때

비교 대상에 문자열이 포함되어 있으면 길이 비교

비교 대상에 문자열이 포함되어 있지 않으면 같은 위치의 ASCII 코드 비교

public class main {
    public static void main(String[] args) throws IOException {
        String subject = "abcd";

                //문자열 포함 - 길이 비교
                subject.compareTo("a"); //3
        subject.compareTo("ab"); //2

                //문자열 포함X - ASCII 코드 비교
        subject.compareTo("c"); //-2 (a와 c 비교)
        subject.compareTo("abfd"); //-3 (c와 f 비교)
        subject.compareTo("zbcd"); //-25
        subject.compareTo("zabc"); //-25
        subject.compareTo("ABCD"); //32

    }

}

[참고] https://mine-it-record.tistory.com/133

[참고] https://st-lab.tistory.com/243

결론: 비교하기 위해 사용하는 메서드들로 본인과 비교할 때는 compareTo()를 사용하고 객체들을 비교하고 오름차순 이외의 정렬을 할 때에는 compare를 사용하면 좋을 것 같습니다 ~