Hash Function
- 해시함수
- 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑해주는 함수
- 해시함수에 의해 얻어지는 값: 해시값, 해시코드, 해시체크섬 또는 간단하게 해시
Hash- 들의 객체 비교
- HashSet, HashMap, HashTable
- 객체가 서로 같은지를 비교하기 위해 equals()메서드와 hashCode()메서드를 호출
- 객체가 서로 같은지 여부를 결정하려면 두 메서드를 재정의 해야 한다.
- HashSet, HashMap, HashTable에서는 객체가 같은지 여부를 데이터를 추가할 때 검사한다.
비교에 쓰이는 두 메서드
equals()
- 두 객체의 내용(값)이 같은지 비교하는 메서드
hashCode()
equals()와 hashCode()에 관한 규칙
- 두 객체가 같으면 반드시 같은 hash code를 가져야 한다.
- 두 객체가 같으면 equals()메서드를 호출했을 때 true를 반환해야 한다.
- 즉, 객체a, b가 같다면 a.equals(b)와 b.equals(a) 둘다 true이어야 한다.
- 두 객체의 hash code가 같다고 해서 두 객체가 반드시 같은 객체는 아니다.
- 하지만, 두 객체가 같으면 반드시 hash code 가 같아야 한다.
- equals()메서드를 override하면 반드시 hashCode()메서드도 override해야 한다.
- hashCode()는 기본적으로 Heap에 있는 각 객체에 대한 메모리 주소 매핑 정보를 기반으로 한 정수값을 반환한다.
- 그러므로, 클래스에서 hashCode()메서드를 override하지 않으면 절대로 두 객체가 같은 것으로 간주될 수 없다.
- hashCode()메서드에서 사용하는 '해싱 알고리즘'에서 서로 다른 객체에 대하여 같은 hash code값을 만들어 낼 수 있다. 그래서 객체가 같지 않더라도 hash code가 같을 수 있다.
예시
비교를 위해 만든 Person 클래스
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;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@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 (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
main
Person p1 = new Person(1, "홍길동");
Person p2 = new Person(1, "홍길동");
Person p3 = new Person(1, "이순신");
System.out.println("p1.equals(p2) : " + p1.equals(p2));
System.out.println("p1 == p2 : " + (p1 == p2));
System.out.println();
Set<Person> set = new HashSet<>();
set.add(p1);
set.add(p2);
set.add(p3));
set.remove(p2));