안녕하세요! 오늘은 헷갈리기 쉬운 숫자로된 문자열을 비교하는 compareTo에 대해 알아보겠습니다.
Comparable을 사용하면서 compareTo를 많이 보았을 것입니다.
오늘은 String class에 구현된 compareTo를 살펴보려고 합니다.
먼저 Comparable<T>의 compareTo() 인터페이스의 시그니쳐를 살펴보겠습니다.
원본과 비교대상이 있을 때
compareTo의 리턴값이 음수면 비교대상이 큰 것, 양수면 원본이 큰 것, 0이면 두 객체는 같다고 판단합니다.
그럼 String class는 이 compareTo를 어떻게 구현하고 있는지 보겠습니다.
- 원본과 비교대상의 길이를 구합니다.
- 두 길이 중 짧은 길이를 선택하여 반복문을 돕니다.
- 각 문자열을 첫번째 문자부터 비교합니다.
- 두 문자가 다르면 '원본 값 - 비교대상 값'을 리턴하고, 같으면 다음 문자를 비교합니다.
(UTF-16으로 인코딩된 값으로 계산됩니다) - 반복문을 돌 때까지 계속 값이 같다면, 결국 문자열 길이를 가지고 계산합니다.
문자열 일때는 직관적으로 사전순 정렬을 예상할 수 있으나,
숫자인 문자열 일때는 많이 헷갈립니다.
총 3개의 경우로 예시를 들어보겠습니다.
1. "12"와 "95"의 대소관계는?
- "12"과 "95"의 길이를 구합니다.
- 두 길이는 같으므로 반복문은 2번 돌게 됩니다.
- "1"과 "9"를 비교합니다.
- 두 문자가 다르므로 "1"-"9" (49-57 = -8) 계산을 하고, 음수가 나왔으므로 비교대상인 "95"가 큰 수가 됩니다.
같은 길이의 문자열일 때는 숫자로 바꿔서 비교할 수 있습니다.
2. "123"과 "9"의 대소관계는?
숫자로 본다면 "123" > "9"일 것 같은데 그렇지 않습니다.
- "123"과 "9"의 길이를 구합니다.
- 9가 총 길이 1로 짧으므로 반복문은 1번 돌게 됩니다.
- "1"과 "9"를 비교합니다.
- 두 문자가 다르므로 "1"-"9" (49-57 = -8) 계산을 하고, 음수가 나왔으므로 비교대상인 "9"가 큰 수가 됩니다.
다른 길이의 문자열일 때는, 맨 앞자리 숫자 문자부터 비교됩니다.
3. "12"과 "123"의 대소관계는?
- "123"과 "12"의 길이를 구합니다.
- 12가 총 길이 2로 더 짧으므로 반복문은 2번 돌게 됩니다.
- "1"과 "1"을 비교합니다.
- 같으므로 다음 인덱스의 값을 비교합니다.
- "2"와 "2"를 비교합니다.
- 같으므로 다음 인덱스를 비교해야하나, 종료조건에 의하여 루프는 끝납니다.
- 결국 길이를 가지고 비교하게 되고, 3 - 2 = 1 양수가 나왔으므로 "123"이 더 큰 수가 됩니다.
다른 길이의 문자열이고 짧은 문자열을 긴 문자열이 모두 포함하고 있다면 문자열의 길이가 긴 것이 큰 숫자문자열이 됩니다.
정리하면, String class의 compareTo는 기본적으로 첫번째 문자부터 하나하나 대소를 비교합니다.
긴 문자열이 짧은 문자열을 포함하고 있다면 문자열의 길이가 긴 것이 크다고 판단합니다.
한글의 경우에 내부적으로 Unicode -> UTF-16 encoding -> char에 들어가서 영문자 처럼 직관적으로 대소를 구분할 수 있습니다.
이건 나중에 한 번 포스팅 해보겠습니다.
궁금한게 있으시면 댓글 남겨주세요 :)
'츄Log > 기타 끄적' 카테고리의 다른 글
헷갈리는 compare/compareTo 이해하기 (0) | 2023.12.09 |
---|---|
Java 스트림 (Stream)의 특징 (1) | 2023.12.08 |
Base64 Encoding (2) | 2023.12.06 |
ASCII Code / Unicode / UTF-8 Encoding / URL Encoding (0) | 2023.12.06 |
싱글톤 안전하게 초기화하기 (thread-safe initialization) (1) | 2023.12.03 |