Java 에서 문자열이 다른 문자열과 같은지 확인하는 방법

JavaBeginner
지금 연습하기

소개

이 랩에서는 Java 에서 문자열을 효과적으로 비교하는 방법을 배우게 됩니다. 문자열 비교를 이해하는 것은 다양한 프로그래밍 작업에 필수적입니다. 두 문자열이 메모리에서 서로 다른 객체일지라도 동일한 문자 시퀀스를 가지고 있는지 확인하기 위한 표준 equals() 메서드를 살펴볼 것입니다.

또한, null 일 수 있는 문자열을 비교할 때 발생할 수 있는 NullPointerException 문제를 처리하는 방법을 배우게 됩니다. 마지막으로, 대소문자를 구분하지 않는 문자열 비교를 수행할 수 있는 equalsIgnoreCase() 메서드를 다룰 것입니다. 이는 문자 비교 로직에서 문자의 대소문자가 중요하지 않을 때 유연성을 제공합니다.

equals() 메서드를 사용하여 문자열 비교하기

이 단계에서는 equals() 메서드를 사용하여 Java 에서 문자열을 비교하는 방법을 배우겠습니다. 문자열 비교는 프로그래밍의 기본 연산이며, 이를 올바르게 수행하는 방법을 이해하는 것이 중요합니다.

Java 에서 문자열은 정수나 부울과 같은 기본 데이터 유형이 아닌 객체입니다. 즉, 문자열을 비교할 때 값뿐만 아니라 객체 자체를 비교하는 것입니다. == 연산자를 사용하여 문자열을 비교하면 두 문자열 변수가 메모리에서 동일한 객체를 참조하는지 확인합니다. 그러나 종종 두 문자열이 서로 다른 객체일지라도 동일한 문자 시퀀스를 가지고 있는지 확인하려고 합니다. 이를 위해서는 equals() 메서드를 사용해야 합니다.

이를 시연하기 위해 간단한 Java 프로그램을 만들어 보겠습니다.

  1. WebIDE 편집기에서 HelloJava.java 파일이 아직 열려 있지 않다면 엽니다.

  2. 파일의 전체 내용을 다음 코드로 바꿉니다.

    public class StringComparison {
        public static void main(String[] args) {
            String str1 = "hello";
            String str2 = "hello";
            String str3 = new String("hello");
    
            System.out.println("Comparing str1 and str2 using equals(): " + str1.equals(str2));
            System.out.println("Comparing str1 and str3 using equals(): " + str1.equals(str3));
            System.out.println("Comparing str1 and str2 using ==: " + (str1 == str2));
            System.out.println("Comparing str1 and str3 using ==: " + (str1 == str3));
        }
    }

    이 코드에서:

    • 세 개의 문자열 변수 str1, str2, str3를 선언합니다.
    • str1str2는 문자열 리터럴을 사용하여 생성됩니다. Java 는 종종 동일한 리터럴이 동일한 객체를 참조하도록 문자열 리터럴을 최적화합니다.
    • str3new String() 생성자를 사용하여 생성됩니다. 이는 내용이 기존 리터럴과 동일하더라도 메모리에 새 문자열 객체를 명시적으로 생성합니다.
    • equals()를 사용하여 문자열의 내용을 비교합니다.
    • ==를 사용하여 문자열 변수가 동일한 객체를 참조하는지 비교합니다.
  3. 파일을 저장합니다 (Ctrl+S 또는 Cmd+S).

  4. 이제 프로그램을 컴파일해 보겠습니다. WebIDE 하단의 터미널을 열고 ~/project 디렉토리에 있는지 확인합니다. 다음 명령을 실행합니다.

    javac StringComparison.java

    컴파일이 성공하면 출력이 표시되지 않습니다. StringComparison.class 파일이 ~/project 디렉토리에 생성됩니다.

  5. 마지막으로, java 명령을 사용하여 컴파일된 프로그램을 실행합니다.

    java StringComparison

    다음과 유사한 출력을 볼 수 있습니다.

    Comparing str1 and str2 using equals(): true
    Comparing str1 and str3 using equals(): true
    Comparing str1 and str2 using ==: true
    Comparing str1 and str3 using ==: false

    str1.equals(str2)str1.equals(str3)가 모두 true를 반환하는 것을 확인하세요. 이는 문자열의 내용이 동일하기 때문입니다. 그러나 str1 == str3false를 반환합니다. 이는 str1str3이 동일한 문자를 포함하고 있음에도 불구하고 메모리에서 서로 다른 문자열 객체를 참조하기 때문입니다. str1 == str2는 이 특정 경우에 문자열 리터럴 최적화로 인해 true를 반환하지만, 문자열 비교에 ==를 사용하는 것은 예상치 못한 결과를 초래할 수 있으므로 일반적으로 권장되지 않습니다.

이는 Java 에서 문자열의 내용을 비교하는 올바른 방법이 equals() 메서드를 사용하는 이유를 보여줍니다.

동등성 검사에서 Null 문자열 처리

이 단계에서는 Java 에서 동등성 검사를 수행할 때 null 문자열을 처리하는 방법을 살펴보겠습니다. null 문자열은 문자열 변수가 어떤 객체도 참조하지 않음을 의미합니다. null 변수에서 메서드를 호출하려고 하면 Java 에서 흔히 발생하는 오류인 NullPointerException이 발생합니다.

문자열을 비교할 때는 하나 또는 두 문자열이 모두 null일 가능성을 고려하는 것이 중요합니다. null 문자열에서 equals() 메서드를 호출하면 프로그램이 충돌합니다.

이것이 어떻게 작동하고 안전하게 처리하는지 확인하기 위해 이전 프로그램을 수정해 보겠습니다.

  1. WebIDE 편집기에서 StringComparison.java 파일을 엽니다.

  2. main 메서드를 수정하여 null 문자열을 포함합니다.

    public class StringComparison {
        public static void main(String[] args) {
            String str1 = "hello";
            String str2 = "hello";
            String str3 = new String("hello");
            String str4 = null; // This string is null
    
            System.out.println("Comparing str1 and str2 using equals(): " + str1.equals(str2));
            System.out.println("Comparing str1 and str3 using equals(): " + str1.equals(str3));
            System.out.println("Comparing str1 and str2 using ==: " + (str1 == str2));
            System.out.println("Comparing str1 and str3 using ==: " + (str1 == str3));
    
            // Let's try comparing with the null string
            // System.out.println("Comparing str1 and str4 using equals(): " + str1.equals(str4)); // This line would cause a NullPointerException
            // System.out.println("Comparing str4 and str1 using equals(): " + str4.equals(str1)); // This line would also cause a NullPointerException
    
            // Correct way to compare when one string might be null
            System.out.println("Comparing str1 and str4 safely: " + (str1 != null && str1.equals(str4)));
            System.out.println("Comparing str4 and str1 safely: " + (str4 != null && str4.equals(str1)));
            System.out.println("Comparing str4 and null safely: " + (str4 == null));
        }
    }

    수정된 코드에서:

    • null 문자열 str4를 추가했습니다.
    • 실행하면 NullPointerException을 발생시키는 줄을 주석 처리했습니다.
    • 하나가 null일 수 있는 경우 문자열을 안전하게 비교하는 방법의 예를 추가했습니다. 가장 안전한 방법은 equals()를 호출하려는 문자열이 메서드를 호출하기 전에 null이 아닌지 확인하는 것입니다. 일반적인 패턴은 (stringVariable != null && stringVariable.equals(anotherString))입니다. 또는 "hello".equals(str4)와 같이 가능한 경우 알려진 null 이 아닌 문자열에서 equals()를 호출할 수 있습니다.
  3. 파일을 저장합니다 (Ctrl+S 또는 Cmd+S).

  4. 터미널에서 수정된 프로그램을 컴파일합니다.

    javac StringComparison.java
  5. 컴파일된 프로그램을 실행합니다.

    java StringComparison

    다음과 유사한 출력을 볼 수 있습니다.

    Comparing str1 and str2 using equals(): true
    Comparing str1 and str3 using equals(): true
    Comparing str1 and str2 using ==: true
    Comparing str1 and str3 using ==: false
    Comparing str1 and str4 safely: false
    Comparing str4 and str1 safely: false
    Comparing str4 and null safely: true

    출력은 안전한 비교가 오류를 발생시키지 않고 null 문자열을 올바르게 처리함을 보여줍니다. str1str4(null) 사이의 비교는 올바르게 false로 평가됩니다.

이 단계는 NullPointerException 오류를 방지하기 위해 Java 에서 객체, 특히 문자열로 작업할 때 null 값을 처리하는 것의 중요성을 강조합니다.

대소문자 구분 없는 비교를 위해 equalsIgnoreCase() 사용

이 마지막 단계에서는 문자의 대소문자를 고려하지 않고 문자열을 비교하는 데 사용되는 equalsIgnoreCase() 메서드에 대해 배우겠습니다. 이는 문자가 대문자인지 소문자인지에 관계없이 두 문자열이 동일한지 확인하려는 경우 매우 유용합니다.

이전 단계에서 사용한 equals() 메서드는 대소문자를 구분하는 비교를 수행합니다. 즉, equals()를 사용하면 "hello"는 "Hello"와 같지 않습니다. equalsIgnoreCase() 메서드는 대소문자를 무시하므로 "hello"와 "Hello"는 동일한 것으로 간주됩니다.

equalsIgnoreCase()를 시연하기 위해 프로그램을 마지막으로 수정해 보겠습니다.

  1. WebIDE 편집기에서 StringComparison.java 파일을 엽니다.

  2. 대소문자가 다른 몇 가지 새로운 문자열 변수를 추가하고 equalsIgnoreCase()를 사용하여 비교합니다.

    public class StringComparison {
        public static void main(String[] args) {
            String str1 = "hello";
            String str2 = "hello";
            String str3 = new String("hello");
            String str4 = null;
            String str5 = "Hello"; // Different casing
            String str6 = "HELLO"; // All uppercase
    
            System.out.println("Comparing str1 and str2 using equals(): " + str1.equals(str2));
            System.out.println("Comparing str1 and str3 using equals(): " + str1.equals(str3));
            System.out.println("Comparing str1 and str2 using ==: " + (str1 == str2));
            System.out.println("Comparing str1 and str3 using ==: " + (str1 == str3));
    
            // Safe comparison with null
            System.out.println("Comparing str1 and str4 safely: " + (str1 != null && str1.equals(str4)));
            System.out.println("Comparing str4 and str1 safely: " + (str4 != null && str4.equals(str1)));
            System.out.println("Comparing str4 and null safely: " + (str4 == null));
    
            System.out.println("\n--- Case-Insensitive Comparisons ---");
            System.out.println("Comparing str1 and str5 using equals(): " + str1.equals(str5));
            System.out.println("Comparing str1 and str5 using equalsIgnoreCase(): " + str1.equalsIgnoreCase(str5));
            System.out.println("Comparing str1 and str6 using equalsIgnoreCase(): " + str1.equalsIgnoreCase(str6));
            System.out.println("Comparing str5 and str6 using equalsIgnoreCase(): " + str5.equalsIgnoreCase(str6));
    
            // equalsIgnoreCase() also handles null safely if called on a non-null string
            System.out.println("Comparing str1 and str4 using equalsIgnoreCase(): " + str1.equalsIgnoreCase(str4));
            // System.out.println("Comparing str4 and str1 using equalsIgnoreCase(): " + str4.equalsIgnoreCase(str1)); // This would still cause a NullPointerException
        }
    }

    업데이트된 코드에서:

    • 대소문자가 다른 str5str6을 추가했습니다.
    • equals()equalsIgnoreCase()의 차이점을 보여주기 위해 새로운 print 문을 추가했습니다.
    • 또한 equals()와 유사하게, null 인수를 사용하여 null 이 아닌 문자열에서 equalsIgnoreCase()를 호출해도 오류가 발생하지 않음을 보여줍니다. 그러나 null 문자열 변수에서 equalsIgnoreCase()를 호출하면 여전히 NullPointerException이 발생합니다.
  3. 파일을 저장합니다 (Ctrl+S 또는 Cmd+S).

  4. 터미널에서 프로그램을 컴파일합니다.

    javac StringComparison.java
  5. 컴파일된 프로그램을 실행합니다.

    java StringComparison

    다음과 유사한 출력을 볼 수 있습니다.

    Comparing str1 and str2 using equals(): true
    Comparing str1 and str3 using equals(): true
    Comparing str1 and str2 using ==: true
    Comparing str1 and str3 using ==: false
    Comparing str1 and str4 safely: false
    Comparing str4 and str1 safely: false
    Comparing str4 and null safely: true
    
    --- Case-Insensitive Comparisons ---
    Comparing str1 and str5 using equals(): false
    Comparing str1 and str5 using equalsIgnoreCase(): true
    Comparing str1 and str6 using equalsIgnoreCase(): true
    Comparing str5 and str6 using equalsIgnoreCase(): true
    Comparing str1 and str4 using equalsIgnoreCase(): false

    출력은 equalsIgnoreCase()가 동일한 문자를 가지고 있지만 대소문자가 다른 문자열을 비교할 때 true를 반환하고, equals()false를 반환함을 명확하게 보여줍니다.

이제 대소문자를 구분하는 비교를 위해 equals()를 사용하고, null 문자열을 안전하게 처리하고, 대소문자를 구분하지 않는 비교를 위해 equalsIgnoreCase()를 사용하는 방법을 배웠습니다. 이는 Java 에서 문자열로 작업하는 데 필수적인 기술입니다.

요약

이 랩에서는 Java 에서 문자열을 비교하는 방법을 배웠습니다. 먼저 == 연산자를 사용하여 문자열 객체를 비교하는 것과 equals() 메서드를 사용하여 내용을 비교하는 것의 차이점을 이해하는 것으로 시작했습니다. ==는 객체 동일성을 확인하고, equals()는 문자 시퀀스 동일성을 확인한다는 것을 알았습니다.

그런 다음 equals()가 호출되는 문자열이 null 이 아닌지 확인하여 문자열을 비교할 때 발생할 수 있는 NullPointerException을 처리하는 방법을 살펴보았습니다. 마지막으로, equalsIgnoreCase() 메서드를 사용하여 대소문자를 구분하지 않는 문자열 비교를 수행하는 방법을 배웠습니다.