CompareTo()
compareTo() 함수는 두개의 값을 비교하여 int 값으로 반환해주는 함수이다. compareTo() 함수에는 “문자열의 비교”와 “숫자의 비교” 두 방식이 존재한다.
숫자의 비교 : 크다(1), 같다(0), 작다(-1)의 결과값을 리턴
문자열 비교 : 같다(0), 그 외 양수/음수값 같이 참 재미난 결과 리턴
비교대상에 문자열이 포함되어 있을 경우
1. 기준값에 비교대상이 포함되어 있을 경우 서로의 문자열 길이의 차이값을 리턴해준다. 예를 보면,
“ab”(2) - “a”(1) = 1
“ab”(2) - “ab”(2) = 0
“”(0) - “ab”(2) = -2
“ab”(2) - “”(0) = 2
public class Test {
public static void main(String[] args) {
String s = "ab";
System.out.println(s.compareTo("a")); // 1
System.out.println(s.compareTo("ab")); // 0
System.out.println(s.compareTo("abc")); // -1
System.out.println(s.compareTo("abcd")); // -2
System.out.println("".compareTo(s)); // -2
System.out.println(s.compareTo("")); // 2
System.out.println(s.compareTo("b")); // -1
System.out.println(s.compareTo("c")); // -2
}
}
2. 처음부터 어느 부분까지는 포함되어 있지만 다른 문자가 나오는 순간이 존재한다면?
기존 문자열 = “abcd”
비교대상 = “abft”
⇒ “ab”는 동일하기 때문에 넘어가고 c와 f 비교에서 비교가 불가능하다. c = 99 / f = 102 이기 때문에 차이값은 아스키코드 값 기준인 -3이 나온다.
비교대상과 전혀 다른 문자열인 경우
compareTo는 같은 위치의 문자만 비교하기 때문에, 첫번째 문자부터 순서대로 비교해서 다를 경우 아스키값을 기준으로 비교처리한다. 즉, “ab”와 “b”를 비교하면 첫 문자부터 다르기 때문에 ' “a”의 아스키코드 - “b”의 아스키코드 = 결과 ' 라는 결과가 나온다.
str.compareTo("zefd") 값은 -25가 나오는데 그 이유는 모두 짐작한거와 같이 a = 97 / z = 122 이기 때문에 차이값인 -25가 반환되며 str.compareTo("ABCD") 이것과 같은 경우는 compareTo의 경우 대소문자를 구분하기 때문에 a = 97 / A = 65 이므로 차이값인 32가 반환되는 것이다.
Comparable()를 이용한 객체 정렬
국어, 영어, 수학 점수를 포함한 학생 5명의 정보가 주어졌을 때, 국어 점수를 기준으로 오름차순 하는 코드를 작성해보자. Java에서는 custom comparator를 만들어야 한다. 이 함수는 반환 타입이 꼭 int 이어야 하며, 해당하는 class를 type으로 하는 1개의 인자를 갖고 있어야만 한다. 가장 일반적인 방법은 class 뒤에 implements Comparable<class type 이름> 을 붙이고 public int compareTO 함수를 class 안에 override annotator와 함께 적어주면 된다. https://www.codetree.ai/missions/5/problems/sort-by-height/introduction
/*
현재 객체(this)에 들어있는 값과 함수로 넘어온 객체 값을 비교했을 때, 오름차순 정렬을 위해서는 다음 조건 3개를 만족시키면 된다.
현재 객체가 정렬 기준 더 뒤에 나와야 한다면 0보다 큰 값을 반환
현재 객체가 정렬 기준 더 앞에 나와야 한다면 0보다 작은 값을 반환
현재 객체가 정렬 기준 우선순위가 함수로 넘어온 객체와 동일하다면, 값 0을 반환
*/
class Student implements Comparable<Student> {
int kor, eng, math;
public Student(int kor, int eng, int math){
this.kor = kor;
this.eng = eng;
this.math = math;
}
@Override
public int compareTo(Student student) { // 국어 점수 기준 오름차순 정렬
if(this.kor > student.kor)
return 1;
else if(this.kor < student.kor)
return -1;
else
return 0;
}
};
Java 8 부터는 정렬 기준을 class 내부에 작성하지 않고, 람다 표현을 통해 함수를 간단히 작성이 가능하다.
Arrays.sort(students, (a, b) -> a.kor - b.kor);
만약 각각 2번에 걸쳐 다른 기준으로 정렬을 하고 싶다면 어떻게 해야할까? 이러한 경우 Arrays.sort로 정렬을 진행하는 순간에 2번째 인자로 comparator를 정의해줄 수 있다. Student 클래스에 대한 Comparator이며, 이는 new Comparator<Student>{} 안에 compare라는 함수를 override하는 형식으로 되어 있다. compare함수는 compareTo함수와 다르게 인자를 2개를 받아 기준을 설정해주어야 하며, 순서대로 a,b라고 했을 때, a는 compareTo에서 this라고 생각하면 된다.
// custom comparator를 활용한 정렬
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student a, Student b) { // 키를 기준 오름차순 정렬합니다.
return a.height - b.height;
}
});