3_[til]hashset과 관련된 개념 동등성, 동일성
hashCode() 오버라이딩 시 준수해야 할 사항
이전에 동등성과 동일성에 대해서는 다룬 적 있으니, 해당 개념은 스킵한다
컬렉션 프레임워크에서, hashSet의 경우 아래와 같은 경우가 존재한다 Person.class
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
그리고 이를 이용해서 HashSet에 추가해보자
HashSet h = new HashSet();
h.add("abc");
h.add("abc");
h.add(new Person("David",10));
h.add(new Person("David",10));
System.out.println("set: "+h);
결과를 출력해보기 전에 추측한다면, HashSet은 중복을 허용하지 않기 때문에 [abc, Person[name=David, age=10]] 이 출력될 것이라고 생각할 것이다
하지만!! 지금 중요한 것은, 컴퓨터가, 컴파일러가, 그들의 입장에서는, ‘어? 음.. 두 객체가 주소가 다르네.. 다른 객체인 것 같네..!’ 라고 생각할 수 있게 만든다!
그러면, 같은 값을 가진 객체가 중복되지 않게 하려면?
동일한 객체로 인식할 수 있도록, hashCode메서드를 오버라이딩해주면 된다!
hashCode를 오버라이딩하면, equals 메서드도 적절히 오버라이딩해주는 것이 좋을 것이다(equals값이 true이면 hashCode도 같아야 하지만, 반대의 경우는 필수까지는 아니다!) ★하지만, 컬렉션의 검색성능 향상을 위해서는 equals가 false를 반환하면 hashCode값이 다른 것이 좋기 때문에 권장된다!
따라서 새로운 클래스 Person2.class를 아래와 같이 작성하고, HashSet에 등록해보자 Person2.class
public class Person2 {
String name;
int age;
public Person2(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person2 other = (Person2) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
이제 HashSet 이 어떻게 되는지 보자
HashSet h = new HashSet();
h.add("abc");
h.add("abc");
h.add(new Person2("David",10));
h.add(new Person2("David",10));
System.out.println("set: "+h);
콘솔에 아름답게 “set: [abc, Person [name=David, age=10]]” 이라고 출력됨을 확인해볼 수 있다