1. equals와 hashCode
- equals와 hashCode는 모든 JAVA 객체의 부모 객체인 Object 클래스에 정의되어 있다. 따라서 모든 JAVA 객체는 Object 클래스의 함수를 상속받는 것이다.
equals()
- boolean equals(Object obj)로 정의된 equals 메소드는 기본적으로 2개의 객체가 동일한지 검사하기 위해 사용된다. equals가 구현된 방법은 2개의 객체가 참조하는 것이 동일한지를 확인하는 것이며, 이는 동일성(Identity)을 비교하는 것이다.
- 즉, 2개의 객체가 가리키는 곳이 동일한 메모리 주소일 경우에만 동일한 객체가 된다.
public boolean equals(Object obj) {
return (this == obj);
}
그러나 실제 프로그래밍에서 동일한 객체가 메모리 상에 여러 개 띄워져있는 경우가 있다. 해당 객체는 서로 다른 메모리에 띄워져있기때문에 동일한 객체가 아니다. 하지만 같은 값을 지니므로 같은 객체로 인식되어야한다. 이러한 동등성을 위해 우리는 값으로 객체를 비교하도록 equals 메소드를 오버라이딩해준다.
hashCode()
- int hashCode()로 정의된 hashCode 메소드는 실행 중에(Runtime) 객체의 유일한 integer값을 반환한다. Object 클래스에서는 Heap에 저장된 객체의 메모리 주소를 반환하도록 되어있다. (항상 그런 것은 아니다.)
public native int hashCode();
equals와 hashCode의 관계
- 동일한 객체는 동일한 메모리 주소를 갖는다는 것을 의미하므로, 동일한 객체는 동일한 해시코드를 가져야한다.
- 따라서 우리가 equals() 메소드를 오버라이드 한다면, hashCode()메소들도 함께 오버라이드 해야한다.
- Java 프로그램을 실행하는 동안 equals에 사용된 정보가 수정되지 않았다면, hashCode는 항상 동일한 정수값을 반환해야 한다. (Java의 프로그램을 실행할 때 마다 달라지는 것은 상관이 없다.)
- 두 객체가 equals()에 의해 동일하다면, 두 객체의 hashCode() 값도 일치해야 한다.
- 두 객체가 equals()에 의해 동일하지 않다면, 두 객체의 hashCode() 값은 일치하지 않아도 된다.
- 즉, obj1.equals(obj2) == True 이면 hashCode(obj1) == hashCode(obj2) 이여야하지만 hashCode(obj1) == hashCode(obj2) 라고 obj1.equals(obj2) == True일 필요는 없다. 하지만 우리는 다른 객체에 대해 동일한 hashCode를 생성한다면 hashTable을 생성하는데 불이익을 받을 수 있음을 인지하고 있어야 한다.
1. equals와 hashCode 오버라이드
만약 아래와 같은 User 클래스가 있다. Uno는 고유값이다.
public class User{
private Integer Uno;
private String Id;
private String Name;
}
public class EqualsTest {
public static void main(String[] args) {
User user1 = new User();
User user2 = new User();
user1.setUno(100);
user2.setUno(100);
System.out.println(user1.equals(user2)); //false
}
}
만약 위와 같이 같은 Uno값을 갖는 2개의 User를 서로 다른 처리과정에 의해 얻었을 경우, 2개의 User는 같은 Uno를 갖기 때문에 true를 반환해야 하지만, 실제 equals는 false를 반환한다. 따라서 이러한 문제를 해결하기 위해 User 클래스에서 equals 메소드를 오버라이드 해야한다.
public boolean equals(Object o) {
if(o == null) {
return false;
}
if (o == this) {
return true;
}
if (getClass() != o.getClass()) {
return false;
}
User user = (User) o;
return (this.getUno() == user.geUno());
}
하지만 아직 끝난 것이 아니다. user1과 user2는 다른 해시값을 반환한다. 따라서 hashCode메소드도 오버라이드해야한다.
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + getUno();
return result;
}
'JAVA' 카테고리의 다른 글
[JAVA] Call by Value & Call by Reference (0) | 2023.02.05 |
---|---|
[JAVA] 예외처리와 올바른 예외처리 방법 (0) | 2023.01.29 |
[JAVA] static에 대하여 (0) | 2023.01.29 |
[JAVA] 객체지향언어2 (0) | 2023.01.29 |
[JAVA] 객체지향언어1 (0) | 2023.01.29 |