[JAVA] equals & hashCode

배세훈·2023년 1월 3일
0

java

목록 보기
16/16

equals()

// Object의 기본 equals 메서드
public boolean equals(Object obj){
	return (this == obj);
}
  • equals는 두 객체를 비교해 내부 value가 같으면 true, 그렇지 않으면 false를 리턴합니다.

equals() 와 ==의 차이

== : 참조값(객체의 주소값)이 같으니 비교합니다.
equals() : 내부의 값이 같은지 비교합니다.

예시) "abc" 라는 값을 가진 a,b 변수의 비교

String a = "abc";
String b = "abc";

System.out.println("a==b ->>> " + a==b);
System.out.println("a.equals(b) ->>> " + a.equals(b));

결과

a==b ->>> false
a.equals(b) ->>> true
  • a==b가 false가 나온 이유는 == 연산자는 a,b의 주소값(참조 값)을 비교하기 때문에 false가 나옵니다. 주소 값은 "abc"라는 값을 저장하기 위한 주소의 값입니다.
  • a.equals(b)가 true가 나온 이유는 a와 b의 내부 값인 "abc"가 같은지만 비교하였기 때문입니다.

primitive 타입이 == 비교를 통해 값 비교가 가능한 이유

  • primitive(원시타입)는 값이 같다면 주소의 값도 동일하게 저장되기 때문입니다.
  • primitive 타입에는 boolean, byte, short, int, long, float, double, char이 있습니다.

hash code

  • 객체를 식별하는 하나의 정수 값입니다.
  • hashCode() 메소드는 객체의 메모리 주소를 이용해서 해시 값을 추출합니다.
  • Collections(HashSet, HashMap, HashTable ...)을 동등한지 비교할 때 사용됩니다.

Collections 비교 과정

업로드중..

  1. hashCode 메서드의 리턴 값이 일치하는지 확인합니다.
  2. equals()를 이용하여 내부 값이 일치하는지 확인합니다.

예시

객체에 equals만 재정의 한 경우

일반 객체 비교, List size, HashSet size를 기반으로 비교하였으며

	class Book{
        String name;

        public Book(String name){
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Book book = (Book) o;
            return Objects.equals(name, book.name);
        }

    }

    @Test
    public void equalsAndHashCodeTest(){
        Book book1 = new Book("Java");
        Book book2 = new Book("Java");

        System.out.println(book1.equals(book2));

        List<Book> bookList = new ArrayList<>();
        bookList.add(book1);
        bookList.add(book2);

        System.out.println("bookList Size >>> " + bookList.size());

        HashSet<Book> bookHashSet = new HashSet<>();
        bookHashSet.add(book1);
        bookHashSet.add(book2);

        System.out.println("bookHashSet Size >>> " + bookHashSet.size());

    }

결과

true
bookList Size >>> 2
bookHashSet Size >>> 2

-> HashSet은 중복을 허용하지 않기 때문에 값이 같은 book1과 book2가 한개로 Set에 등록될 줄 알았지만 Book 객체내에 hashCode 메서드가 재정의 되지 않아서 Object 클래스의 hashCode 메서드가 사용되었습니다. 따라서 book1 과 book2의 hashCode가 다르기 때문에 HashSet에서는 다른 객체로 분리하여 2개가 등록되고 있습니다.

hashCode 재정의

	class Book{
        String name;

        public Book(String name){
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Book book = (Book) o;
            return Objects.equals(name, book.name);
        }

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

equals vs hashCode

  1. equals가 같다면 hashCode는 같습니다.
    -> Collections, 객체, primitive 타입에서 비교시에 equals가 성립하려면 값이 같거나 값과 hashCode가 같아야 하기 때문입니다.

  2. hashCode가 같다고 무조건 equals가 같은건 아닙니다.
    -> primitive 타입에서도 hashCode는 사용하지 않지만 값이 같은 경우 equals가 성립하기 때문입니다. 또한 Collections 타입에서도 hashCode가 같아도 내부 값이 다른 경우 equals가 성립하지 않습니다.

profile
성장형 인간

0개의 댓글

관련 채용 정보