[Java] HashSet과 HashMap에서 equals() hasCode()를 재정의 해주어야 하는 경우
📌equals(),hashcode()
- 자바 최상의 Object 클래스에 equals()와 hascode() 메서드가 있다.
- Object의 equals는 객체의 주소를 비교하여 같은 객체인지 확인한다.
public boolean equals(Object obj){
return (this == obj);
}
✅에제1 오버라이딩 하기전
Person클래스는 name과 age를 맴버변수로 같고 name, age가 같으면 같은 사람으로 인식하도록 하려는 의도로 작성하였다.
public class EX11_11 {
public static void main(String[] args) {
HashSet set = new HashSet();
set.add("abc");
set.add("abc"); //중복이라 저장안됨
set.add(new Person("David", 10));
set.add(new Person("David", 10));
System.out.println(set);
}
}
//equals () 와 hashCode()를 오버라이딩해야 HasSet이 바르게 동작.
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + ":" + age;
}
}
/*출력
[abc, David:10, David:10]
*/
결과를 보면 두인스턴스의 name,age가 같음에도 불구하고 서로 다른것으로 인식하여 David:10이 두번 출력되었다.
이 클래스의 작성의도대로
두인스턴스를 같은 것으로 인식하게 하려면 어떻게 해야할까?
✅에제2 오버라이딩
public class EX11_11 {
public static void main(String[] args) {
HashSet set = new HashSet();
set.add("abc");
set.add("abc"); //중복이라 저장안됨
set.add(new Person("David", 10));
set.add(new Person("David", 10));
System.out.println(set);
}
}
//equals () 와 hashCode()를 오버라이딩해야 HasSet이 바르게 동작.
class Person{
String name;
int age;
Person(String name , int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + ":" + age;
}
@Override
public boolean equals(Object obj == person) {
if(!(obj instanceof Person)) return false;
Person p = (Person) obj;
// 나자신(this)의 이름과 나이를 p와 비교
return this.name.equals(p.name) && this.age == p.age;
}
@Override
public int hashCode() {
// int hash(Object.. values); //....>은 가변인자
return Objects.hash(name, age);
}
}
/*출력
[David:10, abc]
*/
- HashSet의 add()는 새로운 객체를 추가 하기 전에 기존에 저장된 객체와 같은 것인지 확인하기 위해 저장할 객체의 equals()와 hashcod()를 호출한다.
- 현재 eqauls는 오버라이딩 되어있지 않아 객체 주소를 비교한다.
- 오버라이딩 하여 Person클래스에서 두 인스턴스의 name과 age가 같으면 true를 반환하도록 equals를 오버라이딩 하였다.
- Objects클래스의 hash()를 이용해서 메스의 괄호 안에 클래스의 인스턴스 변수들을 넣어 오버라이딩하였다.
결과값 =>[David:10, abc] 출력
✅정리
- Object의 equals와 hashCode는 객체의 주소를 가지고 계산을 한다.
- 우리는 equals를 객체의 주소가 아닌 다른 비교로 바꾸어주어야 할 경우가 있다.
- 이떄 HashSet,HashMap뿐만 아니라 haschode로도 객체를 비교하기떄문에 hashCode도 재정의 해주어야한다.
ref https://ksabs.tistory.com/188
Leave a comment