[java] 동일성과 동등성

Jifrozen·2022년 11월 1일
0

기초 다지기

목록 보기
19/29

동일성(indentity)

동일하다는 뜻으로 두 객체가 완전히 같은 경우를 의미한다.
완전히 같다는 것은 두 객체의 주소값이 같기때문에 같은 객체 즉 하나의 객체로 봐도 무방하다.
동일성을 판단하는 연산자는 ==연산자이며 Primitive타입의 객체는 주소가 없기때문에 같은 값을 가지면 동일하다고 본다.

동등성(equality)

동등하다는 뜻으로 두 객체가 같은 정보를 갖고 있는 경우를 의미한다.
동등성은 변수가 참조하고 있는 객체의 주소가 다르더라도 내용만 같으면 두 변수는 동등하다고 이야기할 수 있다. 동일하면 동등하지만 동등하다고 해서 동일한건 아니다. 동등성을 판단하는 연산자는 equals이다.

equals 연산자

eqauls 연산자가 무조건 동등성을 판단하는것은 아니다. 모든 객체의 조상인 Object에서 정의하고 있는 equals 메서드를 봐보자.

public boolean equals(Object obj) {
    return (this == obj);
}

반환형태를 보면 단순하게 동일성 비교를 하고 있다. 즉 ==연산자와 같은 역할을 하는것이다.
그렇다면 equals를 이용해 동등성을 어떻게 파악할 수 있을까?
오버라이드를 통해 재정의된 equals를 살펴보자.

String의 equals 연산자

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

동일하면 동등하기 때문에 ==연산자를 통해 동일성을 파악한다.
동일하지 않으면 String 문자열을 char형식으로 한글자씩 비교해 동등한지 비교한다.

Integer의 equals 연산자

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

Integer의 equals는 Integer인지 확인한 후 값을 비교해 동등한지 비교한다.

Objects의 equals 연산자

public static boolean equals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
}

Objects 클래스에서 재정의한 equals를 보자.
a==b를 통해 동일성을 파악한다. 동일하지 않아도 또는 연산자를 통해 a과 b의 동등성을 파악한다. 여기서 equals는 a객체에서 재정의한 equals 통해 파악한다. 만약 a 객체에서 equals를 재정의하지 않았다면 Object equals를 사용하게 되어 동등성 대신 동일성을 파악하게 된다. 그렇기 때문에 커스텀 객체를 만들었을 때, equals를 쓰게된다면 꼭 재정의 과정이 필요하다.

hashCode()도 함께 오버라이드 해야 하는 이유는?

객체를 collection에서 사용할 때, 동등성 비교가 가능할까?
Hash의 경우 어떤 데이터가 존재하는지 확인하기 위해 해싱 알고리즘을 사용한다. 해싱된 결과를 주소값으로 찾아가서 그곳에 같은 자료가 있는지 확인한다. 그 해싱 알고리즘에서 사용하는 데이터가 hashCode()이다.
Object의 hashCode()는 그 객체의 주소값을 반환하기 때문에(동일성) 동등성을 비교하기 위해선 hashCode를 재정의해야한다.
따라서, 객체의 동등성을 위해 equals메소드를 오버라이드하는 경우,
hashCode메소드도 오버라이드 해야 한다.

@Override
   public int hashCode() {
       return Objects.hash(name);
   }

이렇게 해줘야 주소값이 아닌 name값으로 객체 비교가 가능하다.

<선생님들>
https://steady-coding.tistory.com/534
https://creampuffy.tistory.com/140

0개의 댓글