CodeGym /행동 /JAVA 25 SELF /문자열 비교: equals, equalsIgnoreCase, compareTo

문자열 비교: equals, equalsIgnoreCase, compareTo

JAVA 25 SELF
레벨 9 , 레슨 4
사용 가능

1. 참조와 내용 비교

Java에서 문자열은 원시형이 아니라 객체입니다. 변수 ab를 작성하면, 이 둘은 문자열 풀의 동일한 문자열을 가리킬 수 있습니다. 반면 생성자를 통해 만든 c는 별도의 객체입니다. 연산자 ==는 텍스트가 아니라 참조(주소) 자체를 비교합니다.

String a = "hello";
String b = "hello";
String c = new String("hello");

System.out.println(a == b); // true (대개 intern된 문자열)
System.out.println(a == c); // false (서로 다른 객체)

오류 데모

String s1 = "Java";
String s2 = new String("Java");
System.out.println(s1 == s2); // false

문자열이 같아 보이지만, 메모리에서는 서로 다른 객체입니다.

2. equals(): 문자열 내용 비교

내용 자체를 비교하려면 equals() 메서드를 사용하세요. 이 메서드는 문자열을 문자 단위로 비교하며(대소문자 구분).

String s1 = "Java";
String s2 = new String("Java");
System.out.println(s1.equals(s2)); // true

예: 비밀번호 비교

String inputPassword = "Secret123";
String realPassword = "Secret123";
if (inputPassword.equals(realPassword)) 
{
    System.out.println("접근이 허용되었습니다!");
} 
else 
{
    System.out.println("비밀번호가 올바르지 않습니다.");
}

중요!

둘 중 하나라도 객체가 null이면 equals() 호출은 NullPointerException을 일으킵니다. 안전한 패턴:

if ("무언가".equals(someString)) { ... }

3. equalsIgnoreCase(): 대소문자 무시 비교

대소문자를 무시해야 할 때(예: 사용자 입력), equalsIgnoreCase()를 사용하세요.

String name1 = "Ivan";
String name2 = "ivan";
System.out.println(name1.equalsIgnoreCase(name2)); // true

예: 이메일 주소 비교

String email1 = "User@Example.com";
String email2 = "user@example.com";
if (email1.equalsIgnoreCase(email2))
{
    System.out.println("이메일이 일치합니다!");
}

요약: equals vs equalsIgnoreCase

메서드 대소문자 구분? 예시 "Java" vs "java"
equals()
false
equalsIgnoreCase()
아니오
true

4. compareTo(): 문자열의 사전식 비교

메서드 compareTo()는 사전식(lexicographical) 비교를 수행합니다. 첫 번째 문자열이 “작으면” 음수, 0이면 같고, “크면” 양수를 반환합니다.

System.out.println("apple".compareTo("banana")); // < 0
System.out.println("apple".compareTo("apple"));  // 0
System.out.println("banana".compareTo("apple")); // > 0

a.compareTo(b) →
   < 0 — esli a idyot ran'she b
   0   — esli ravny
   > 0 — esli a idyot posle b
사전식 비교: compareTo() 결과

동작 원리

  • 비교는 문자들의 Unicode 코드 포인트를 기준으로 왼쪽에서 오른쪽으로 진행됩니다.
  • 처음으로 다른 문자를 만나면 그 코드 포인트의 차이를 반환합니다.
  • 한 문자열이 다른 문자열의 접두사라면, 더 짧은 쪽이 “작다”고 판단됩니다.
System.out.println("cat".compareTo("catalog")); // < 0 ("cat"가 더 짧음)
System.out.println("catalog".compareTo("cat")); // > 0

예: 문자열 배열 정렬

String[] fruits = {"banana", "apple", "pear"};
Arrays.sort(fruits); // 내부적으로 compareTo()를 사용함
System.out.println(Arrays.toString(fruits)); // [apple, banana, pear]

compareToIgnoreCase()

System.out.println("Java".compareToIgnoreCase("java")); // 0

5. startsWith() 및 endsWith() 메서드

메서드 startsWith()endsWith()는 문자열의 시작과 끝을 확인하며 true/false를 반환합니다.

String fileName = "document.pdf";
String url = "https://www.google.com";

System.out.println(fileName.startsWith("doc"));  // true
System.out.println(fileName.endsWith(".txt"));   // false
System.out.println(url.startsWith("https://"));  // true

왜 필요할까요: 형식 검증(파일 이름, URL)과 접두사/접미사 기반 필터링에 유용합니다(예: 모든 ".jpg").

6. contains(): 부분 문자열 검색

contains(CharSequence s)는 부분 문자열의 존재를 확인하는 간단한 방법입니다. 대소문자를 구분합니다.

String text = "Java의 세계에 오신 것을 환영합니다!";
System.out.println(text.contains("세계"));   // true
System.out.println(text.contains("C++"));   // false

대소문자를 무시하려면 두 문자열을 동일한 대소문자로 변환하세요: toLowerCase()/toUpperCase().

7. toLowerCase()와 toUpperCase() 메서드

새 문자열을 반환하며, 각각 소문자 또는 대문자로 변환합니다. 대소문자에 독립적인 비교와 포매팅에 유용합니다.

String title = "Java Programming";
String lower = title.toLowerCase();
String upper = title.toUpperCase();

System.out.println(lower); // java programming
System.out.println(upper); // JAVA PROGRAMMING

8. split(): 문자열을 분할하기

split(String regex)는 구분자(정규식)를 기준으로 문자열을 분할하고 배열 String[]을 반환합니다.

예 1: 쉼표로 분할

String names = "Alex,Maria,Ivan,Elena";
String[] nameArray = names.split(",");
for (String name : nameArray) 
{
    System.out.println(name.trim()); // trim()은 남아 있을 수 있는 공백을 제거합니다
}
// 출력:
// Alex
// Maria
// Ivan
// Elena

예 2: 공백으로 분할

String sentence = "나는 Java를 공부한다";
String[] words = sentence.split(" ");
for (String word : words) 
{
    System.out.println(word);
}
// 출력:
// 나는
// Java를
// 공부한다

특징:

  • 구분자는 정규식입니다. 특수 문자는 이스케이프해야 합니다(예: 마침표: "\\.").
  • 이 메서드는 요소가 하나뿐이어도 항상 배열을 반환합니다.

9. 실습: 실제 애플리케이션에서 문자열 비교

String registeredEmail = "user@example.com";
String registeredPassword = "Secret123";

Scanner console = new Scanner(System.in);

System.out.print("이메일을 입력하세요: ");
String email = console.nextLine();

System.out.print("비밀번호를 입력하세요: ");
String password = console.nextLine();

// 이메일은 대소문자 무시, 비밀번호는 대소문자 구분
if (email.equalsIgnoreCase(registeredEmail) && password.equals(registeredPassword))
{
    System.out.println("환영합니다!");
}
else
{
    System.out.println("이메일 또는 비밀번호가 올바르지 않습니다.");
}

설명: 이메일에는 equalsIgnoreCase()를, 비밀번호에는 엄격히 equals()를 사용합니다. 문자열에는 == 연산자를 사용하면 안 됩니다 — 참조를 비교하기 때문입니다.

10. 문자열 비교 시 흔한 실수

실수 №1: 문자열을 ==로 비교하고 equals()를 사용하지 않음
연산자 ==는 참조를 비교하며, 내용이 아니기 때문에 결과가 예상과 다를 수 있습니다.

실수 №2: equals()null일 수 있는 객체에서 호출함
항상 null이 아님을 보장하는 객체에서 메서드를 호출하거나 Objects.equals(a, b)를 사용하세요.

실수 №3: 대소문자가 중요한데 이를 무시함
예를 들어, 비밀번호는 대소문자를 구분해서 비교해야 합니다. 요구사항을 확인하세요.

실수 №4: 문자열을 다른 타입의 객체와 비교함
"123"123은 동일하지 않습니다. equals()는 타입을 자동으로 변환하지 않습니다.

실수 №5: 대소문자가 섞인 문자열을 그냥 정렬함
대문자가 소문자보다 먼저 옵니다. 대소문자를 무시하고 정렬하려면 Arrays.sort(array, String.CASE_INSENSITIVE_ORDER)를 사용하세요.

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION