[Java] 문자열의 비교 (equals override)
두 개의 문자열을 비교할 때는 비교연산자 "==" 대신 equals() method를 사용하는 게 좋다.
String str = "abc";
Java에서 문자열을 만들 때 보통 위 코드처럼 간결하게 변수 선언 후 값 대입하는 형식으로 만든다.
하지만 사실 String은 클래스이므로, new 연산자를 이용해 객체를 생성해야 한다.
String str = new String("abc");
위 코드처럼 new 키워드를 사용해 String 객체를 생성해야 하는데, Java에서 특별히 String만 new를 사용하지 않고 간단히 사용할 수 있다.
String이 객체라는 사실
String str1 = "ab";
String str2 = "ab";
System.out.printf("str1==str2: %b%n",str1==str2);
String str3 = "ab";
String str4 = new String("ab");
System.out.printf("str3==str4: %b%n",str3==str4);
str1==str2는 리터널로 선언한 문자열이다. 자바 컴파일러는 String Constant Pool이라는 영역에 문자열이 같은 것끼리 공유하여 메모리를 최적화한다. 결론은 리터널로 선언한 같은 값의 문자열은 같은 객체 주소를 가리킨다.
하지만 new 연산자를 사용하면 새로운 문자열 객체를 생성하는 것이다. Heap 영역에 저장되며, 문자열 값이 같다 하더라도 주소가 다르다.
객체주소를 비교하는 게 아니라 문자열 값만 비교한다면 Java에서 제공하는 equals metod를 사용하는 게 좋다.
public static void main(String[] args){
String str1 = new String("a");
String str2 = new String("a");
System.out.printf("비교연산자(==) 사용: %b%n", str1==str2);
System.out.printf("equals() 사용: %b%n", str1.equals(str2));
}
equals method는 적절히 오버라이드하여 다양한 객체를 비교할 수 있다.
ex)
public class hello {
public static void main(String[] args) {
Student st1 = new Student("kim",111);
Student st2 = new Student("kkk",111);
System.out.println(st1.equals(st2));
}
}
class Student{
int studentNum;
String name;
Student(){}
Student(String name,int num){
this.name = name;
this.studentNum = num;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Student) {
Student std = (Student) obj;
if (this.studentNum == std.studentNum) {
return true;
} else {
return false;
}
}
return false;
}
}
위 코드는 Student 클래스의 num의 값으로만 비교하게끔 equals method를 오버라이드했다.
오버라이드 없이 그냥 일반적으로 equals method를 사용했으면 false가 출력된다.
만약 문자열을 대소문자 구분 없이 비교하고 싶으면, equalsIgnoreCase() 메서드를 사용하면 된다.
String str1 = new String("abc");
String str2 = new String("ABC");
System.out.printf("str1.equalsIgnoreCase(str2): %b%n",str1.equalsIgnoreCase(str2));
결론
- 문자열은 객체이다. (리터널로 간단히 선언 가능, new 연산자로 생성 가능)
- 리터널로 선언한 문자열들은 값이 같으면, 비교연산자 true가 나온다
- 리터널로 선언한 문자열들은 String Constant Pool이라는 곳에 같은 값을 가진 문자열끼리 객체주소를 같은 걸 가리킨다.
- new 연산자를 사용하면 Heap에 선언되며 저장된다. 문자열 값이 같아도 객체주소가 달라 비교연산자가 아닌 equals를 사용해야 true 유도할 수 있음.
사진출처
https://kor.pngtree.com/freepng/java-programming-icon_6044136.html