본문 바로가기

Java

equals() Overriding

 자동차 미션을 테스트하는 중에 List<Car>에 담긴 Car객체의 Name과 Position이 잘 담겼는지 테스트하는 상황이 왔었다. 하지만 테스트를 위해 작성한 예상 객체와 실제 객체는 주소가 다르므로 값이 같아도 다르다는 결과가 나왔다.
 그래서 값 자체를 빼와서 테스트를 진행했는데, 이보다 좋은 방법을 발견하여 작성해본다.

 

모든 Object 형 객체는 기본적으로 equals() 메소드와 hashCode() 메소드를 가진다.

이 중 equals()는 두 객체가 동일한 객체인지 테스트하는 메소드이다.

 

 

 

 

 

이 동일한 객체가 무엇이냐면,

class Car{
	private String name;

	public Car(String name) {
    	this.name = name;
    }
}
Car car1 = new Car("티코");
Car car2 = new Car("티코");

위의 car1, car2는 다른 객체다. 속성이 같다 해도.

객체는 생성될 때 마다 힙영역에 고유하게 생성되므로 Assertions.assertEquals 테스트를 돌려도 다르다는 결과가 나온다.

car1.equals(car2); // false

@Test
Assertions.assertEquals(car1, car2); // false

 

동일하다는 것은 메모리상에 저장된 주소가 같은 같은 객체를 가리키냐를 말한다.

 

 

 

 

 

 

 

하지만 우리는 equals()라는 메소드로 '값이 같으면 같은 객체' 라는 결과를 얻고 싶다.

그렇다면 클래스에서 equals() 메소드를 오버라이딩하여 재정의하면 된다.

class Car{
	private String name;

	public Car(String name) {
    	this.name = name;
    }
    
    @Override
    public boolean equals(Object obj) {
    	Boolean isT = false;
        Car car = (Car) o;
        if (name.equals(car.getName())) {
            isT = true;
        }
        return isT;
    }
    
    @Override
    public int hashCode() {
    	final int prime = 31;
	int hashCode = 1;

	hashCode = prime * hashCode + ((name == null) ? 0 : name.hashCode());

	return hashCode;
    }
}

 

 

여기서 hashCode() 함수는 객체의 메모리 주소값을 변환하여 정수형으로 반환한다.

 

equals() 메소드로 객체가 같음을 재정의했지만, 객체의 메모리 주소값은 여전히 다른 상태다.

 

이런 점은 hashCode()를  이용하는 Collections(HashMap..)에서 문제가 될 수 있는데, 

car1, ca2가 같음을 equals()에서 정의했다면, 키값으로 car1, car2가 다르게 들어가도 같은 키값으로 인식해야 한다.

 

hashCode()는 특정 알고리즘에 의해 생성되는 값이므로 우연히 값이 같을 수 도 있겠다.

하지만 다를 수 도 있다는 말이다.

 

HashMap에서는 key값을 hashCode()로 계산하는데, 

car1, car2가 equals()로 같은 객체라고 정의했지만, hashCode값이 다르다면 다른 key값이 되는 것이다.

 

 

 

따라서 equals()와 hashCode()를 모두 true로 처리할 수 있는 동일성 조건을 세우면 사용자의 혼란을 막을 수 있다.

 

hashCode() 는 비교하고자 하는 객체의 속성값이 같으면 같다라고 판단할 수 있게 속성을 이용하여 유일한 값을 가질 수 있게 짜면 된다.

 

 

참고 : nesoy.github.io/articles/2018-06/Java-equals-hashcode

'Java' 카테고리의 다른 글

함수형 인터페이스  (0) 2020.12.11
static 메소드 사용  (0) 2020.12.09
String과 StringBuilder  (0) 2020.12.06
Arrays.asList()  (0) 2020.12.06
Google Java Style Guide(번역)  (0) 2020.11.28