-
Java 인스턴스 비교Computer Science/JAVA 2020. 12. 21. 22:33
코드
import java.util.HashSet; public class Test { public static void main(String[] args) { HashSet set = new HashSet(); set.add(new Person("David", 10)); set.add(new Person("David", 10)); System.out.println(set); } } class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return name + " : " + age; } }
결과
- 위의 코드에서 이름과 나이가 같으면 같은 사람으로 인식하고 HashSet에 중복으로 들어가지 않게 하기 위한 의도로 작성하였다.
- 하지만 실행결과를 보면 name과 age의 값이 같음에도 불구하고 서로 다른 것으로 인식하여 중복해서 출력되고 있다.
→ 이 두 인스턴스를 같은 것으로 인식하게 하려면 어떻게 해야할까
수정 코드
import java.util.HashSet; import java.util.Objects; public class Test { public static void main(String[] args) { HashSet set = new HashSet(); set.add(new Person("David", 10)); set.add(new Person("David", 10)); System.out.println(set); } } class Person { String name; int age; Person(String name, int age) { this.name = name; this.age = age; } public boolean equals(Object obj) { if(obj instanceof Person) { Person tmp = (Person)obj; return name.equals(tmp.name) && age == tmp.age; } return false; } public int hashCode() { return Objects.hash(name, age); } public String toString() { return name + " : " + age; } }
HashSet의 add 메서드는 새로운 요소를 추가하기 전에 기존에 저장된 요소와 같은 것인지 판별하기 위해 추가하려는 요소의 equals()와 hashCode()를 호출하기 때문에 equals()와 hashCode()를 목적에 맞게 오버라이딩 해야합니다.
equals()의 리턴 값이 true이고 hashCode()의 리턴 값이 같다면 같은 인스턴스로 간주합니다.
hashCode()의 조건
실행 중인 애플리케이션 내의 동일한 객체에 대해서 여러 번 hashCode()를 호출해도 동일한 int 값을 반환해야 합니다.
equals 메서드를 이용한 비교에 의해서 true를 얻은 두 객체에 대해 각각 hashCode()를 호출해서 얻은 결과는 반드시 같아야 합니다.
equals 메서드를 호출했을 때 false를 반환하는 두 객체는 hashCode() 호출에 대해 같은 int 값을 반환하는 경우가 있어도 되지만, 해싱을 사용하는 컬렉션의 성능을 향상시키기 위해서는 다른 int 값을 반환하는 것이 좋습니다.
(Hashtable이나 HashMap과 같은 해시코드를 사용하는 컬렉션의 성능을 높이기 위함)
'Computer Science > JAVA' 카테고리의 다른 글
String, StringBuilder, StringBuffer (0) 2021.08.20 Object 클래스 (0) 2021.08.20 예외 처리 (0) 2021.08.12 Maven vs Gradle (0) 2021.01.18 JVM 이해하기 (0) 2021.01.12