Java String - 비교하기
문자열 비교에는 String 타입으로 할당한 변수를 "==
" 사용하지 않고 "equals()
" 메소드로 비교해야한다.
비교에 사용되는 용어
- 동일성(Identity): "
==
" 연산자를 사용해 두 객체가 참조가 동일한지 확인한다. - 동등성(Equality): "
equals()
" 메소드를 사용해 두 객체가 갖고 있는 문자가 논리적으로 같은지 확인하기
문자열 풀 (String Pool)
다음 코드에서 String 문자열을 객체로 직접 사용한 케이스와 리터럴로 할당하는 경우의 코드를 살펴본다.
StringPoolMain.java
public class StringPoolMain {
public static void main(String[] args) {
String str1 = new String("Hello"); // 새 객체 생성
String str2 = new String("Hello"); // 새 객체 생성
System.int.println("String str1, str2 comparison = " + (str1 == str2));
System.int.println("String str1, str2 comparison = " + (str1.equals(str2)));
String str3 = "Hello"; // 새 객체 생성
String str4 = "Hello"; // String Pool 동일한 문자열을 가진 객체 참조 할당
System.int.println("String str3, str4 comparison = " + (str3 == str4));
System.int.println("String str3, str4 comparison = " + (str3.equals(str4)));
}
}
출력 결과
String str1, str2 = false
String str1, str2 = true
String str3, str4 = true
String str3, str4 = true
코드에서 String str3 = "Hello";
리터럴로 직접 할당하는 경우 자바는 메모리 효율과 성능 최적화로 문자열 풀(String Pool)을 사용한다.
문자열 풀은 클래스에 리터럴이 있으면 문자열 풀에서 String 인스턴스를 생성한다. (같은 문자열인 경우 생성하지 않음)
이어서 String str4 = "Hello";
다시 리터럴로 같은 문자열을 할당하는 경우 문자열 풀에서 가져와 객체 참조를 사용한다.
문자열 풀 사용 이유는 메모리 사용을 줄이고 문자를 만드는 시간 성능을 최적화 한다.
용어 정리
풀(Pool): 프로그래밍에서 풀은 자원이 모여있는 곳을 말한다. 공용 자원을 한 곳으로 모아 여러 곳에서 함께 사용한다. 새 객체가 필요한 경우에 생성하고 매번 제거하는 것은 비효율적으로 문자열 풀이 생기게 되었다.
자바의 문자열 풀은 힙 영역에 생성되어 해시 알고리즘을 사용하고 있다.
해시 알고리즘는 O(1) 속도로 문자열을 빠르게 찾는다.
비교문 == 자바에서 권장되지 않는 이유
다음 메소드가 있다고 가정
public static boolean isSame(String src, String dest) {
return src == dest;
}
해당 메소드를 개발자가 new String(..) 선언하여 사용하는 개발자와 리터럴로 직접 변수(src = "hello")에 할당하는 개발자가 있다면 서로의 결과가 다를 것이다. 원활한 협업을 위해 String 클래스의 equals 메소드로 비교문으로 사용하도록 한다.
public static boolean isSame(String src, String dest) {
return src.equals(dest);
}