자바(Java)에서는 객체를 비교할 때
== 연산자와 equals() 메소드를 구분해서 사용한다.
이 둘은 역할이 다르며, 헷갈리기 쉽지만 정확히 구분해야 한다.
| 비교 방법 | 비교 대상 | 의미 | 결과 |
|---|---|---|---|
== | 기본형(primitive), 객체 참조(reference) | 메모리 주소(참조) 비교 | 같은 객체를 가리키면 true |
equals() | 객체(object) | 값(내용) 비교 (기본은 주소 비교, 필요 시 오버라이드) | 값이 같으면 true |
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false : 서로 다른 객체
System.out.println(a.equals(b)); // true : 값(내용)이 같음
new String("hello")는 항상 새로운 객체를 생성한다.a와 b는 다른 메모리 주소를 가진다 (==은 false).equals() 호출 시 true가 나온다.class Person {
String name;
Person(String name) {
this.name = name;
}
}
Person p1 = new Person("Kim");
Person p2 = new Person("Kim");
System.out.println(p1 == p2); // false
System.out.println(p1.equals(p2)); // false (equals를 오버라이드 안 했기 때문)
Person 클래스는 equals() 메소드를 오버라이드하지 않았다.equals()도 기본적으로 == 비교를 수행한다.equals()를 제대로 활용하려면 반드시 오버라이드해야 한다.
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return Objects.equals(name, person.name);
}
getClass())name 필드를 비교이제 두 Person 객체는 이름이 같으면 equals()가 true가 된다.
HashSet, HashMap 같은 자료구조는
equals()로 값이 같은지 확인하고hashCode()로 빠른 검색을 한다.중요:
equals()를 오버라이드하면 반드시 hashCode()도 같이 오버라이드해야 한다.
@Override
public int hashCode() {
return Objects.hash(name);
}
== : "주소값 비교"다. 같은 객체인지 물어본다.equals() : "내용 비교"다. 클래스에 따라 오버라이드 되어 있을 수도 있다.String, Integer 같은 기본 클래스는 equals()가 오버라이드 되어 있다.equals()를 오버라이드해야 제대로 비교할 수 있다.equals()를 오버라이드하면 hashCode()도 같이 오버라이드해야 Hash 자료구조에서 정상 동작한다.