Closed choigy1001 closed 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를 사용하고 있습니다.
본질적으로 다시 생각해보면 두 인터페이스 모두 객체의 비교 기준을 세우기 위해 만들어졌다는게 핵심이라고 생각합니다. 큰 차이점은 비교하는 대상이 다르다이겠네요.
결론적으로 두 인터페이스를 구현하여 사용하는 시기는
(무적의 문장 같아서 죄송하지만) 상황에 맞게 사용하는 것이 적절하다는게 제 결론이네요.
사용 예시 - 백준 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를 사용하면 좋을 것 같습니다 ~
비교하는 메서드를 구현한다는 의미는 같습니다. 하지만 어떤 상황에 더 적합한지를 알면 조금 더 쉽게 사용할 수 있을거 같습니다. 저 또한 정리해서 여기에 올려두겠습니다!