두 객체가 같으면 반드시 같은 hashcode를 가져야 한다.
두 객체가 같으면 equals()메서드를 호출했을 때 true를 반환해야 한다. 즉, 객체 a, b가 같다면 a.equals(b)와 b.equals(a) 둘 다 true이어야 한다.
두 객체의 hashcode가 같다고 해서 두 객체가 반드시 같은 객체는 아니다. 하지만, 두 객체가 같으면 반드시 hashcode가 같아야 한다.
4.equals()메서드를 override하면 반드시 hashCode()메서드도 override해야 한다.
hashCode()는 기본적으로 Heap에 있는 각 객체에 대한 메모리 주소 매핑정보를 기반으로 한 정수 값을 반환한다. int값 반환!!!!
그러므로, 클래스에서 hashCode()메서드를 override하지 않으면 절대로 두 객체가 같은 것으로 간주 될 수 없다.
hashCode()메서드에서 사용하는 '해시 알고리즘'에서 서로 다른 객체에 대하여 같은 hashcode값을 만들어 낼 수 있다. 그래서 객체가 같지 않더라도 hashCode가 같을 수 있다.
모리기반으로 되어있기 때문에 적절하게 재정의할 필요성이 있다.
public static void main(String[] args) {
//3개의 Person 객체
Person p1 = new Person(1,"홍길동");
Person p2 = new Person(1,"홍길동");
Person p3 = new Person(1,"이순신");
System.out.println("p1.equals(p2) :"+p1.equals(p2));
// hashcode() equals() 오버라이드 자동완성 켰을때 true , 껐을때 false
System.out.println("p1.equals(p1) :"+p1.equals(p1)); //true
System.out.println("p1==p2 :"+(p1==p2)); //true
//Person을 담을 HashSet
Set<Person> set = new HashSet<>();
//순서가 없고 중복 허용X
set.add(p1);
set.add(p2);
System.out.println("p1,p2 등록 후 데이터");
for(Person p:set) {
System.out.println(p.getId()+":"+p.getName());
//p1만 등록 p2는 중복체크에 걸려서 추가X => 1:홍길동
}
System.out.println("add(p3) 성공 여부 :"+set.add(p3));//true
System.out.println("p3 등록 후 데이터");
for(Person p:set) {
System.out.println(p.getId()+":"+p.getName());
//1:홍길동 1:이순신
}
System.out.println("remove(p2) 성공 여부: "+set.remove(p2));//true
System.out.println("remove(p2) 후 데이터");
for(Person p:set) {
System.out.println(p.getId()+":"+p.getName());
// p2와 p1과 같은 데이터로 생각 =>1:이순신
}
}
}
class Person{
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//자동완성
@Override
public int hashCode() {
final int prime = 31;//prime : 소수
int result = 1;
result = prime * result + id; // 31+1 = 32
result = prime * result + ((name == null) ? 0 : name.hashCode()); // 삼항연산자
return result;
}
@Override
public boolean equals(Object obj) {// obj:p2
if (this == obj)//(p1==p1)
return true;
if (obj == null)//(p2==null)
return false;
if (getClass() != obj.getClass())
return false;
//p1에 대한 getClass p2 Person에 대한 getclass
Person other = (Person) obj;//(Person)으로 캐스팅
if (id != other.id)//내가 갖고 있는 id와 p1의 id와 다를때
return false;
if (name == null) { //p1이 null이고
if (other.name != null) //p2는 null이 아니다
return false;
} else if (!name.equals(other.name))//p1의 네임이 p2의 네임과 같지 않으면
return false;
return true;
}
}