문자열과 숫자를 비교하여 int 값으로 반환해주는 함수이다.
문자열을 비교하는 경우
0
: 두 문자열이 같은 경우음수
: 인자가 객체보다 사전적으로 순서가 앞인 경우양수
: 객체가 인자보다 사전적으로 순서가 앞인 경우숫자를 비교하는 경우
0
: 두 숫자가 같은 수인 경우음수
: 인자가 객체보다 큰 수인 경우양수
: 객체가 인자보다 큰 수인 경우// java 11
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
숫자열 비교는 기준값과 비교대상의 크기를 비교한 경과를 반환한다. 동일한 경우 0
, 기준 값이 작은 경우 -1
, 기준값이 비교대상보다 큰 경우 1
을 반환하는 규칙을 따른다.
public static void main(String[] args) {
Integer x = 3;
Integer y = 4;
Double z = 1.0;
System.out.println(x.compareTo(y)); // -1
System.out.println(x.compareTo(3)); // 0
System.out.println(x.compareTo(2)); // 1
System.out.println(z.compareTo(2.7)); // -1
}
숫자열 타입은 Integer, Double, short 등을 비교할 수 있다. 기준값과 비교대상의 타입이 다르면 비교할 수 없다.
// java 11
public int compareTo(String anotherString) {
byte v1[] = value;
byte v2[] = anotherString.value;
if (coder() == anotherString.coder()) {
return isLatin1() ? StringLatin1.compareTo(v1, v2)
: StringUTF16.compareTo(v1, v2);
}
return isLatin1() ? StringLatin1.compareToUTF16(v1, v2)
: StringUTF16.compareToLatin1(v1, v2);
}
문자열 비교하는 코드를 살펴보면 isLatin1()
메서드로 문자열이 LATIN1로 인코딩 되었는지, UTF16로 인코딩 되었는지 검사한다. Java는 기본적으로 UTF-16 인코딩을 사용하는데, 이는 2바이트가 사용되기 때문에 힙 사용에서 손해를 본다. 이를 위해 Java 9부터는 ISO-8859-1(Latin-1) 문자 집합으로 표현 가능한 문자를 1byte로 저장하기 시작했다.
이제 compareTo로 반환해주는 값들이 어떻게 나오는지 알아보자.
public static void main(String[] args) {
String a = "abcd";
System.out.println(a.compareTo("abcd")); // 0
System.out.println(a.compareTo("ab")); // 2
System.out.println(a.compareTo("a")); // 3
System.out.println(a.compareTo("c")); // -2
System.out.println("".compareTo(a)); // 4
}
기준값에 비교대상이 포함되어 있는 경우, 문자열의 길이 차이값을 반환한다.
문자열을 비교하는 코드는 다음과 같다.
// StringLatin1.java
@HotSpotIntrinsicCandidate
public static int compareTo(byte[] value, byte[] other) {
int len1 = value.length;
int len2 = other.length;
return compareTo(value, other, len1, len2);
}
public static int compareTo(byte[] value, byte[] other, int len1, int len2) {
int lim = Math.min(len1, len2);
for (int k = 0; k < lim; k++) {
if (value[k] != other[k]) {
return getChar(value, k) - getChar(other, k);
}
}
return len1 - len2;
}
그럼 a.compareTo("c")
는 왜 -2라는 값이 나올까?
compareTo는 두 문자열에서 같은 위치의 값을 비교하기 때문에 값이 다를 경우, 아스키 코드의 차이를 비교해준다.
위 경우 "abcd"와 "c"라는 문자열의 0번째 인덱스에서 비교를 실패했다. a와 c의 아스키 코드는 각각 97, 99이다.
compareTo는 대소문자를 구분한다. 즉 a와 A를 비교한다면 a는 97, A는 이므로 이 둘의 차이인 32가 반환되는 것이다. 대소문자를 무시하고 싶다면 compareToIgnoreCase를 사용하면 된다.
Summary
compareTo()
로 숫자열과 문자열을 비교할 수 있다.- 숫자열은 숫자의 크기로 비교한다.
- 문자열은 문자를 사전순으로 비교한다.
Reference