Java에서 문자열을 비교하는 다양한 방법을 알아보겠습니다.
다른 언어와 다르게 Java는 ==
로 문자열이 같은지 확인하지 않습니다. ==
는 object가 동일한지를 체크하기 때문에 object가 갖고 있는 문자열이 동일하다는 것을 보장하지 않기 때문입니다.
어떤 방법이 잘못되었고, 어떤 방법으로 비교할 수 있는지 예제와 함께 알아보겠습니다.
1. equals()으로 문자열 비교
다음과 같이 equals()
를 사용하여 두개의 문자열이 동일한지 비교할 수 있습니다. 객체의 순서를 바꿔도 결과는 동일합니다.
String str1 = "Hello";
String str2 = "World";
String str3 = "Hello";
System.out.println("str1.equals(str2) : " + str1.equals(str2));
System.out.println("str2.equals(str1) : " + str2.equals(str1));
System.out.println("str1.equals(str3) : " + str1.equals(str3));
Output:
str1.equals(str2) : false
str2.equals(str1) : false
str1.equals(str3) : true
equals()
는 모든 객체의 부모 클래스인 Object에 정의되어있는 메소드입니다.
String 클래스는 다음과 같이 equals()
를 오버라이드하여 인자로 전달된 String의 문자열을 비교하고 있습니다.
간단히 코드를 보면 ==
키워드로 객체가 갖다면 더 확인하지 않고 true를 리턴합니다. 객체가 다른 경우 인자가 String이라면 문자열을 비교하여 동일한지 결과를 리턴해 줍니다.
// String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
NullPointerException
equals()
를 사용하면서 주의할 점은 다음과 같이 str1
이 null이라면 NullPointerException
이 발생합니다.
String str1 = null;
String str2 = "World";
System.out.println("a.equals(b) : " + str1.equals(str2));
하지만 인자로 전달되는 객체는 null이라도 NullPointerException
가 발생하지 않습니다.
String str1 = "Hello";
String str2 = null;
System.out.println("a.equals(b) : " + str1.equals(str2));
NullPointerException이 발생하는 것에 대해서 신경쓰고 싶지 않다면(예외처리를 하고 싶지 않다면) Objects.equals()
를 사용하여 두개의 객체를 비교할 수 있습니다.
System.out.println("str1 == str2 ? " + Objects.equals(str1, str2));
System.out.println("str1 == str3 ? " + Objects.equals(str1, str3));
Objects.equals()
구현 코드를 보면, 자체적으로 Null에 대한 예외처리를 하기 때문에 NullPointerException이 발생하지 않습니다.(false가 리턴 됨)
// Objects.java
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
NullPointerException에 대해 좀 더 알고 싶으시면 "Java - NullPointerException 원인, 해결 방법"을 참고해주세요.
대소문자 구분
그리고 문자열을 비교할 때 대소문자도 구분하여 비교합니다. 대소문자를 구분하지 않고 알파벳이 같은지만 보려면 equalsIgnoreCase()
를 사용해야 합니다.
String str = "Hello";
System.out.println("equals ? " + "Hello".equals(str));
System.out.println("equalsIgnoreCase ? " + "hello".equalsIgnoreCase(str));
Output:
equals ? true
equalsIgnoreCase ? true
2. == 를 이용하여 문자열 비교
==
를 이용하여 문자열을 비교하면 안됩니다. 잘못된 방식이며, 자바에서는 이런 방식을 허용하지 않습니다.
아래 예제를 보시면, 문자열이 같지만 false
를 리턴하는 경우도 있다는 것을 알 수 있습니다.
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println("str1 == str2 ? " + (str1 == str2));
System.out.println("str1 == str3 ? " + (str1 == str3));
System.out.println("str1 hashCode ? " + System.identityHashCode(str1));
System.out.println("str2 hashCode ? " + System.identityHashCode(str2));
System.out.println("str3 hashCode ? " + System.identityHashCode(str3));
Output:
str1 == str2 ? true
str1 == str3 ? false
str1 hashCode ? 1789447862
str2 hashCode ? 1789447862
str3 hashCode ? 38997010
==
는 객체가 같은지(객체의 Hashcode)를 비교하지만 객체가 갖고 있는 문자열이 같은지 비교하지 않습니다.
str1
과 str2
는 모두 동일한 문자열 "Hello"
를 가리키기 때문에 같은 object입니다. 하지만 str3
는 new String()
으로 만든 객체로 이 둘과 다릅니다.
System.identityHashCode()
는 object의 hashCode를 리턴하는 메소드인데요. 이것을 이용하면 str1
과 str3
는 문자열은 같지만 서로 다른 객체라는 것을 알 수 있습니다.
자바 객체의 Hashcode에 대한 자세한 내용이 궁금하시다면 "Java - hashCode(), 사용하는 이유? 구현 방법?"를 참고하세요.
3. compareTo()를 이용하여 문자열 비교
compareTo()는 두개의 문자열을 비교합니다. 두개의 문자열이 같은지 확인할 수 있는 equals()
와 다르게 어떤 문자가 사전적인 순서로 앞에 있는지도 결과 값으로 리턴합니다.
따라서 compareTo()
를 이용하면 리스트를 오름차순으로 정렬하거나 내림차순으로 정렬할 수 있습니다.
리턴 값은 0, 음수, 양수의 int가 리턴되며 의미는 다음과 같습니다.
- 0 : 두개의 문자열이 동일
- 양수 :
compareTo()
를 호출하는 객체가 인자보다 사전적으로 순서가 앞설 때 - 음수 : 인자가 객체보다 사전적으로 순서가 앞설 때
다음과 같이 사용할 수 있습니다.
String str1 = "Hello";
String str2 = "Hello";
String str3 = "World";
System.out.println("str1.compareTo(str2) ? " + str1.compareTo(str2));
System.out.println("str1.compareTo(str3) ? " + str1.compareTo(str3));
System.out.println("str1.compareToIgnoreCase(str2) ? " + str1.compareToIgnoreCase(str2));
System.out.println("str1.compareToIgnoreCase(str3) ? " + str1.compareToIgnoreCase(str3));
Output:
str1.compareTo(str2) ? 0
str1.compareTo(str3) ? -15
str1.compareToIgnoreCase(str2) ? 0
str1.compareToIgnoreCase(str3) ? -15
str1.compareTo(str3)
가 -15
를 리턴한다는 것은 str1이 str3보다 사전적으로 앞에 있다는 의미입니다.
또한, 대소문자를 구분하지 않고 비교하려면 compareToIgnoreCase()
를 사용하면 됩니다.
compareTo()을 이용하여 배열을 정렬하는 원리가 궁금하시다면 "Java - 배열 정렬(Sorting) (오름차순, 내림차순)"를 참고해보세요.
4. 참고
Related Posts
- Java - Unsupported class file major version 61 에러
- Java - String.matches()로 문자열 패턴 확인 및 다양한 예제 소개
- Java - 문자열 공백제거 (trim, replace)
- Java - replace()와 replaceAll()의 차이점
- Java - ArrayList 초기화, 4가지 방법
- Java - 배열 정렬(Sorting) (오름차순, 내림차순)
- Java - 문자열(String)을 비교하는 방법 (==, equals, compare)
- Java - StringBuilder 사용 방법, 예제
- Java - 로그 출력, 파일 저장 방법 (Logger 라이브러리)
- Java IllegalArgumentException 의미, 발생 이유
- Java - NullPointerException 원인, 해결 방법
- Seleninum의 ConnectionFailedException: Unable to establish websocket connection 해결
- Java - compareTo(), 객체 크기 비교
- Java - BufferedWriter로 파일 쓰기
- Java - BufferedReader로 파일 읽기
- Java charAt() 함수 알아보기
- Java - BigInteger 범위, 비교, 연산, 형변환
- Java contains()로 문자(대소문자 X) 포함 확인
- Java - Set(HashSet)를 배열로 변환
- Java - 문자열 첫번째 문자, 마지막 문자 확인
- Java - 문자열 한글자씩 자르기
- Java - 문자열 단어 개수 가져오기
- Java - 1초마다 반복 실행
- Java - 배열을 Set(HashSet)로 변환
- Java - 여러 Set(HashSet) 합치기
- Java - 명령행 인자 입력 받기
- Java - 리스트 역순으로 순회, 3가지 방법
- Java - 특정 조건으로 리스트 필터링, 3가지 방법
- Java - HashMap 모든 요소들의 합계, 평균 계산
- Java - 특정 조건으로 HashMap 필터링
- Java - 싱글톤(Singleton) 패턴 구현
- Java - 숫자 왼쪽에 0으로 채우기
- Java - String 배열 초기화 방법
- Java - 정렬된 순서로 Map(HashMap) 순회
- Java - HashMap에서 key, value 가져오기