일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- JPA
- 누적합
- ai agent
- 완전탐색
- 레디스 동시성
- 아키텍쳐 개선
- 검색어 추천
- 프로그래머스
- 쿠키
- jwt 표준
- gRPC
- 추천 검색 기능
- 몽고 인덱스
- 크롤링
- langgraph
- ipo 매매자동화
- BFS
- 디버깅
- 카카오
- 백준
- 구현
- AWS
- 트랜잭샨
- piplining
- 결제서비스
- next-stock
- 셀러리
- docker
- 이분탐색
- spring event
- Today
- Total
코딩관계론
Java에서 equals와 hashCode 메서드를 재정의해야 하는 이유 본문
"Why do I need to override the equals and hashCode methods in Java?"를 검색하면, 다음과 같은 답변이 나옵니다:
[StackOverflow: Why do I need to override the equals and hashCode methods in Java?](https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java)
You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object.hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.
equals() 메서드를 재정의하는 모든 클래스에서 반드시 hashCode() 메서드도 재정의해한다. 이를 하지 않는다면 Object.hashCode()에 대한 일반 계약이 위반되어 HashMap, HashSet, Hashtable과 같은 해시 기반 컬렉션과 함께 클래스가 제대로 작동하지 않게 됩니다.
Object.hashCode()`의 일반 계약이란
1. 일관성: 동일한 객체에 대해 여러 번 hashCode 메서드를 호출할 때, 객체의 equals 비교에 사용되는 정보가 수정되지 않는 한, 항상 동일한 정수를 반환해야 합니다. 단, 애플리케이션의 다른 실행에서는 이 정수가 일관되지 않아도 됩니다.
2. 동일성: 두 객체가 equals 메서드에 따라 같다고 간주되면, 이 두 객체에 대해 hashCode 메서드를 호출하면 동일한 정수 결과를 반환해야 합니다.
3. 불일치: 두 객체가 equals 메서드에 따라 같지 않다고 간주되더라도, hashCode 메서드가 서로 다른 정수 결과를 반환할 필요는 없습니다. 하지만, 같지 않은 객체에 대해 서로 다른 정수 결과를 생성하는 것이 해시 테이블의 성능을 향상할 수 있습니다.
계약 위반 시 문제점
만약 `equals`를 재정의하면서 `hashCode`를 재정의하지 않으면, `HashMap`, `HashSet`, `Hashtable`과 같은 해시 기반 컬렉션에서 클래스가 제대로 작동하지 않게 됩니다. 이는 해시값을 기반으로 객체가 저장될 버킷(bucket)을 결정하고, 해당 버킷에 객체를 저장하는 해시 컬렉션의 동작 방식 때문입니다.
다음 예제를 통해 이 문제를 구체적으로 살펴보겠습니다.
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (age != other.age)
return false;
return true;
}
}
import java.util.HashSet;
public class App {
public static void main(String[] args) throws Exception {
Person person1 = new Person("John", 30);
Person person2 = new Person("John", 30);
HashSet<Person> persons = new HashSet<Person>();
persons.add(person1);
persons.add(person2);
System.out.println(person1.equals(person2)); // 출력결과: true
System.out.println(persons.size()); // 출력결과: 2
}
}
위 코드에서 `equals` 메서드는 `true`를 반환하지만, `HashSet`의 크기는 2입니다. 이는 `hashCode` 메서드를 재정의하지 않았기 때문입니다.
hashCode 메서드 Override 후
다음과 같이 `hashCode` 메서드를 추가합니다
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + age;
return result;
그리고 메인 함수를 다시 호출하면
import java.util.HashSet;
public class App {
public static void main(String[] args) throws Exception {
Person person1 = new Person("John", 30);
Person person2 = new Person("John", 30);
HashSet<Person> persons = new HashSet<Person>();
persons.add(person1);
persons.add(person2);
System.out.println(person1.equals(person2)); // 출력결과: true
System.out.println(persons.size()); // 출력결과: 1
}
}
이제 `HashSet`의 크기는 1이 됩니다. 이는 `equals`와 `hashCode` 메서드를 모두 올바르게 재정의했기 때문입니다.
참고 자료
- [StackOverflow: Why do I need to override the equals and hashCode methods in Java?](https://stackoverflow.com/questions/2265503/why-do-i-need-to-override-the-equals-and-hashcode-methods-in-java)
Why do I need to override the equals and hashCode methods in Java?
Recently I read through this Developer Works Document. The document is all about defining hashCode() and equals() effectively and correctly, however I am not able to figure out why we need to ov...
stackoverflow.com
- [Hashcode docs]
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#hashCode()
Object (Java SE 17 & JDK 17)
java.lang.Object public class Object Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class. Since: 1.0 See Also: Constructor Summary Constructors Method S
docs.oracle.com
'개발 > Java' 카테고리의 다른 글
Thread Safety하게 만들자 (0) | 2024.06.09 |
---|---|
static, final 어디까지 알아보고 왔는가? (0) | 2024.06.09 |
JVM 메모리 구조 (0) | 2024.06.08 |
자바 어떻게 실행되는가? (0) | 2024.06.02 |
[실무 역량 과제] 신규 유형 (BE) (0) | 2024.05.30 |