
Java에서 두 값을 비교할 때 == 연산자와 equals() 메서드를 사용할 수 있습니다.
그러나 이 둘은 동작 방식이 다르며, 사용 목적도 다릅니다.
| 비교 방식 | 설명 |
|---|---|
| == 연산자 | 두 개의 참조값(메모리 주소)을 비교 |
| equals() 메서드 | 두 개의 객체 내용(값)을 비교 |
== 연산자는 기본적으로 두 개의 변수가 같은 객체를 참조하는지 확인할 때 사용됩니다.
즉, 객체의 메모리 주소를 비교합니다.
public class Main {
public static void main(String[] args) {
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(str1 == str2); // false (주소값이 다름)
}
}
equals() 메서드는 객체 내부의 값이 같은지 비교할 때 사용됩니다.
일반적으로 객체의 내용이 같은지 확인하기 위해 오버라이딩하여 사용합니다.
class Person {
String name;
Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return this.name.equals(person.name);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice");
Person p2 = new Person("Alice");
System.out.println(p1.equals(p2)); // true (내용이 동일)
}
}
Java에서 String 객체는 리터럴 풀(String Pool) 을 사용하기 때문에,
리터럴로 선언된 문자열은 같은 객체를 참조할 수도 있습니다.
public class Main {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1 == str2); // true (리터럴 풀에서 같은 객체 공유)
System.out.println(str1 == str3); // false (new 키워드로 새로운 객체 생성)
System.out.println(str1.equals(str3)); // true (내용이 같음)
}
}
객체 비교를 위해 equals()를 오버라이딩할 경우, hashCode()도 함께 오버라이딩하는 것이 일반적입니다.
이는 HashMap, HashSet 등의 컬렉션에서 객체를 비교할 때 일관성을 유지하기 위해 필요합니다.
import java.util.Objects;
class Car {
String model;
Car(String model) {
this.model = model;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Car car = (Car) obj;
return Objects.equals(model, car.model);
}
@Override
public int hashCode() {
return Objects.hash(model);
}
}