equals()
-
자바 문자열의 객체(Object)의 내용 혹은 문자열(String)비교를 할 때 사용한다.
-
boolean equals(Object obj)로 정의된 equals 메서드는 기본적으로 2개의 객체가 동일한지 검사하기 위해 사용된다.
-
equals가 구현된 방법은 2개의 객체가 참조하는 것이 동일한지를 확인하는 것이며, 이는 동일성(Identity)을 비교하는 것이다.
-
즉, 2개의 객체가 가리키는 곳이 동일한 메모리 주소일 경우에만 동일한 객체가 된다.
비교 연산자와 equals() 메서드의 차이
== (비교 연산자)
==연산자는 주로 두 개의 객체 주소의 값을 비교한다.(참조 타입(Reference Type), Call By Reference)- 주소의 값이란 실제 내용의 값이 아닌 자료의 위치의 값이다
- 즉, 두 객체가 메모리 상에서 같은 위치를 참조하고 있는지를 검사한다.
equals() 메서드
- equals() 메서드(Method)는 객체(Object)의 내용 비교한다.(원시 타입(Primitive Type), Call By value)
Java
- 따라서 문자열을 비교할때에는 == 보다는 equals를 사용해야 한다.
동등성
-
프로그래밍을 하다보면 동일한 객체가 메모리 상에 여러 개 띄워져있는 경우가 있다.
-
해당 객체(Object)는 서로 다른 메모리에 띄워져있으므로 동일한(Identity) 객체(Object)가 아니다.
-
하지만 프로그래밍 상으로는 같은 값을 지니므로 같은 객체로 인식되어야 하는데, 이러한 동등성(Equality)를 위해 우리는 값으로 객체를 비교하도록 equals 메서드를 오버라이딩(Overriding)해주는 것이다.
-
예를 들어 아래와 같이 동일한 값을 갖는 문자열을 2개 생성하면 각각은 서로 다른 메모리에 할당되므로 동일하지 않다.(힙 영역에 생성된다.)
-
대신 같은 값(원시 타입(Primitive Type)을 지니므로 동등하다.
-
하지만 동일성을 비교하는 equals 메서드를 호출해보면 true가 나오는데, 그 이유는 **String 클래스에서 equals 메소드를 오버라이드하여 객체가 같은 값을 갖는지 동등성(Equality)을 비교하도록 처리했기 때문이다.
equals와 hashCode의 관계
-
동일한 객체는 동일한 메모리 주소를 갖는다는 것을 의미하므로, 동일한 객체는 동일한 해시코드를 가져야 한다.
-
그렇기 때문에 우리가 equals() [[메서드(Method)**를 오버라이딩(Overriding)한다면, hashCode() 메서드(Method)도 함께 오버라이딩(Overriding) 되어야 한다.
-
이러한 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을 생성하는데 불이익을 받을 수 있음을 인지하고 있어야 한다.
equals와 hashCode의 Override
equals() Override의 필요성
- 만약 아래와 같은 Employee 클래스가 있다고 하자.
- Employee는 id를 고유값으로 갖는다.
Java
- 만약 아래와 같이 같은 id 값을 갖는 2개의 Employ를 서로 다른 처리 과정에 의해 얻었다고 하자.
- 2개의 Employee는 같은 id를 갖기 때문에 equals 연산을 한다면 true를 반환해야 한다.
- 하지만 아래의 예제는 깊게 볼 필요도 없이 false를 반환할 것이다.
Java
- 이러한 문제를 해결하기 위해 우리는 Employ에 다음과 같은 equals 메서드를 오버라이딩(Overriding) 해야 한다.
Java
- 이제 equals에 의한 문제는 해결된 것 처럼 보인다.
- 하지만 우리가 Employee를 HashSet과 같은 자료구조에 저장하려고 하면 또 다른 문제가 생기게 된다.
hashCode() Override의 필요성
-
앞서 설명한대로 HashTable이나 HashSet, HashMap과 같은 자료구조는 자료를 저장하기 위한 위치를 선택하기 위해 hashCode()를 이용한다.
-
그렇다면 우리가 수정한 Employee를 HashSet에 저장하면 어떤 결과가 나올까?
Java
-
Object 클래스의 hashCode() 메소드는 해당 메모리 주소값을 반환한다고 설명하였다.
-
그렇기 때문에 위의 e1과 e2는 다른 해시값을 반환할 것이고, HashSet에는 2개의 객체가 서로 다른 위치에 저장될 것이다.
-
우리는 이러한 문제를 해결하기 위해 hashCode 메소드도 Employee 클래스에 오버라이드하여 수정해주어야 한다.
Java
- 이러한 작업을 모두 거치면 hashSet에도 1개의 데이터만 저장되게 된다.
equals로 null 체크 하는 방법
Java