ballqs 님의 블로그
[Java] Comparator compare() 과 Comparable compareTo() 본문
예전에 정렬에 관련된 게시물을 작성한 적이 있다.
Array.sort와 Collections.sort의 차이점 이다. 하지만 여기에서는 말그대로 sort에 관련된 것만 작성했고
Comparator 과 Comparable 를 이용한 정렬이 아니였다. 그래서 작성하여 메모해두려고 한다.
Comparator compare()
Comparator Interface를 찾아보면 compare()라는 메서드가 있고 int를 반환하도록 되어있다.
compare() 메서드는 매개변수를 기반으로 비교한다.
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
Person person1 = new Person("홍길동" , 30);
Person person2 = new Person("홍길서" , 20);
// 자기 자신의 객체를 넣어도 또는 다르게 생성한 객체를 넣어도 무관
System.out.println(person1.compare(person1 , person2));
// 출력 결과 : 1
}
}
class Person implements Comparator<Person> {
private String name;
private int age;
Person(String name , int age) {
this.name = name;
this.age = age;
}
// 구현되어 있는 메서드를 보면 2개의 메서드를 받아와서 비교
@Override
public int compare(Person o1, Person o2) {
if (o1.age > o2.age) {
return 1;
} else {
return 0;
}
}
}
위 코드와 같이 어느 객체에 포함해서 구현해도 상관 없지만 Comparator 기능만 따로 두고 싶을땐 익명 객체를 활용하면 된다.
import java.util.Comparator;
public class Test {
public static void main(String[] args) {
// 익명 객체
// 사용 방법1
// Comparator<Person> comp = new Comparator<>() {
// @Override
// public int compare(Person o1, Person o2) {
// if (o1.age > o2.age) {
// return 1;
// } else {
// return 0;
// }
// }
// };
// 사용 방법2(람다)
Comparator<Person> comp = (o1, o2) -> {
if (o1.age > o2.age) {
return 1;
} else {
return 0;
}
};
Person person1 = new Person("홍길동" , 30);
Person person2 = new Person("홍길서" , 20);
System.out.println(comp.compare(person1 , person2));
}
}
class Person {
String name;
int age;
Person(String name , int age) {
this.name = name;
this.age = age;
}
}
그렇게 매개변수 2개를 받아 비교한 결과값을 기반으로 정렬된다.
정렬 기준은 아래와 같다.
- 음수일 경우 : 두 원소의 위치를 교환 안함
- 양수일 경우 : 두 원소의 위치를 교환 함
Comparable compareTo()
Comparable Interface를 찾아보면 compareTo 라는 메서드가 있고 이 메서드 또한 int를 반환하도록 되어있다.
compareTo는 자기 자신을 기준으로 삼아서 값을 비교해 나간다.
아래의 코드를 보면 직접 구현하여 테스트해보았다.
package camp;
public class Test {
public static void main(String[] args) {
Person person1 = new Person("홍길동" , 30);
Person person2 = new Person("홍길서" , 20);
System.out.println(person1.compareTo(person2));
// 출력 값 : 10
}
}
class Person implements Comparable<Person>{
String name;
int age;
Person(String name , int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
}
코드 기반으로 보게 되면 30 - 20 이라서 출력 값이 10 이 나온다.
여기서 주의 해야 할 점이 있다. 두 수의 대소 비교를 통해 값을 반환 받으니까 연산 과정에서 int의 값을 넘어버리는 경우도 발생할 수 있으니 이부분 알아놓자!
아 그리고 무조건 알아가야하는 게 있는데 직접 구현이 아니라 만들어진 걸 사용 하려면
참조형 데이터 타입 으로 진행해야 사용 가능하다.
또한compareTo() 함수는 두개의 값을 비교하여 int값을 반환하기에 숫자형 비교와 문자형 비교때 다르게 동작하는게 있다.
숫자형 비교는 위에 적어놓은 코드대로 동작하며 대소비교를 통해 크다(1) , 같다(0) , 작다(-1) 을 리턴하지만 저렇게 Override를 하는 경우 그 이외의 값도 리턴이 가능해진다.
다만 문자열 비교가 재미 있게 동작한다.
public class Test{
public static void main(String[] args){
String str = "abcd";
// 문자열이 같을 경우 0을 리턴
System.out.println( str.compareTo("abcd") ); // 0
// 문자열 뒷부분만 다를때 아스키 코드 기반으로 d = 100 / f = 102 여서 빼면 -2 가 나온다.
System.out.println( str.compareTo("abcf") ); // -2
// 문자열 길이가 다를 경우에는 문자열 길이에 대한 차이를 리턴한다.
System.out.println( str.compareTo("ab") ); // 2
System.out.println( str.compareTo("a") ); // 3
System.out.println( str.compareTo("c") ); // -2
System.out.println( "".compareTo(str) ); // -4
// 문자열 앞부분이 다를때 아스키 코드 기반으로 a = 97 / z = 122 여서 빼면 -25 가 나온다.
// 중간은 계산안하는 듯 하다
System.out.println( str.compareTo("zefd") ); // -25
System.out.println( str.compareTo("zEFd") ); // -25
// 대소문자도 구분하여 아스키 코드 기반으로 계산
System.out.println( str.compareTo("ABCD") ); // 32
}
}
compareTo에 대해 모르는게 많았는데 이렇게라도 메모해두고 사용하자.
'코딩 공부 > Java' 카테고리의 다른 글
[Java] Stack를 활용한 DFS 알고리즘으로 푼 문제 (0) | 2024.08.16 |
---|---|
[Java] 투 포인터(Two Pointer) 알고리즘이란? (0) | 2024.08.13 |
[Java] BFS(Breadth-First Search) 알고리즘이란? (0) | 2024.08.05 |
[Java] 문제 풀다가 조금 더 깊게 DFS 알고리즘 경험 (0) | 2024.07.31 |
[Java] 문제 풀다가 간접적 DFS 알고리즘 경험 (0) | 2024.07.30 |