compareTo로 값(숫자열/문자열) 비교하기

wnajsldkf·2022년 10월 28일
0

Java

목록 보기
13/19
post-thumbnail

compareTo()

문자열과 숫자를 비교하여 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로 반환해주는 값들이 어떻게 나오는지 알아보자.

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

profile
https://mywnajsldkf.tistory.com -> 이사 중

0개의 댓글