Part2. 5-13 중복되지 않게 자료를 관리하는 Set 인터페이스를 구현한 클래스와 그 활용 (HashSet 클래스)
Set 인터페이스를 활용해보자
HashSet 클래스 (Hash: 딕션너리 , Set: 집합)
* Set 인터페이스를 구현한 클래스 (집합, 튜플)
* 객체(멤버)의 중복 여부를 체크하기 위해 인스턴스의 동일성을 확인해야 함 (집합이니까 중복 x 여서 중복 여부를 체크해야 함)
* 동일성 구현을 위해 필요에 따라 equals()와 hashCode()메서드를 재정의함
* HashSet에 데이터가 add될 때 안에서 add되는 객체에 대해 equals() 메서드와 hashCode() 메서드를 체크한다.
그래서 이전에 있던 것과 동일하면 add를 하지 않는다.
equals 메서드 : 두 인스턴스의 주소를 비교하는 메서드
hashCode 메서드 : 인스턴스의 주소를 반환하는 메서드
public class HashSetTest {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<String>();
hashSet.add(new String("김유신"));
hashSet.add(new String("이순신"));
hashSet.add(new String("홍연의"));
hashSet.add(new String("강감찬"));
hashSet.add(new String("강감찬"));
System.out.println(hashSet);
}
}
import java.util.HashSet;
improt java.util.Iterator;
public class MemberHashSet {
private HashSet<Member> hashSet;
public MemberHashSet(){
hashSet = new HashSet<Member>();
}
public void addMember(Member member){
hashSet.add(member);
}
public boolean removeMember(int memberId){
Iterator<Member> ir = hashSet.iterator();
while( ir.hasNext()){
Member member = ir.next();
int tempId = member.getMemberId();
if( tempId == memberId){
hashSet.remove(member);
return true;
}
}
System.out.println(memberId + "가 존재하지 않습니다");
return false;
}
public void showAllMember(){
for(Member member : hashSet){
System.out.println(member);
}
System.out.println();
}
}
public class MemberHashSetTest {
public static void main(String[] args) {
MemberHashSet memberHashSet = new MemberHashSet();
Member memberLee = new Member(1001, "이순신");
Member memberKim = new Member(1002, "김유신");
Member memberKang = new Member(1003, "강감찬");
memberHashSet.addMember(memberLee);
memberHashSet.addMember(memberKim);
memberHashSet.addMember(memberKang);
memberHashSet.showAllMember();
Member memberHong = new Member(1003, "홍길동"); //1003 아이디 중복
memberHashSet.addMember(memberHong);
memberHashSet.showAllMember();
}
}
JDK에서 스트링이나 인티저를 보면 equals 랑 hashcode가 다 구현되어 있다.
스트링은 스트링의 시퀀스가 같으면 같은 얘이고 그 시퀀스를 가지고 hashCode 값을 제너레이트 한다.
인티저 같은 경우는 인티저의 value가 같으면 같은 얘이고 hashCode의 반환값은 int value 값이 반환된다
인티저 100이라고 하면 그 100을 반환한다.
아이디(1003)가 동일한 경우 중복이므로 중복되지 않도록 Member 클래스의 equals()와 hashCode()메서드를 재정의해야 한다.
@Override
public int hashCode() {
return memberId; // 다른게 반환되는 게 아닌 아이디가 반환되도록 재정의
}
@Override
public boolean equals(Object obj) {
if( obj instanceof Member){ // obj가 Member인 경우
Member member = (Member)obj; // 다운캐스팅
if( this.memberId == member.memberId ) // 논리적으로 동일?
return true;
else
return false;
}
return false;
}
hashCode 메서드와 equals 메서드를 재정의 하기만 하면 요소를 추가할 때 HashSet 내부에서 자동으로 중복체크를 한다.
(와우! 자동화!) (미리 잘 만들어진 클래스를 활용만 하면 된다.)
두 메서드의 순서는 hashCode() --> equals() 순서이다.
Collection 프레임워크 안에 있는 HashSet은 클래스이고 Set은 인터페이스이다.
hashSet 클래스는 Set<E> 인터페이스를 구현했고 내부적으로는 HashMap을 이용해서 요소들을 저장한다.