2018-6-5 Collection Framework (2) - Set
Set Interface
Set<E>를 구현하는 클래스의 특성과 HashSet<E>
Set<E> 인터페이스의 특징
- 저장 순서가 유지되지 않는다.
- 데이터의 중복을 허락하지 않는다.
set은 수학에서 말하는 집합의 특성이다.
package yoon;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetCollectionFeature {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Toy");
set.add("Box");
set.add("Robot");
set.add("Box");
System.out.println("인스턴스의 수 : " + set.size());
for(Iterator<String> itr = set.iterator(); itr.hasNext(); )
System.out.print(itr.next() + "\t");
System.out.println();
for (String s: set)
System.out.print(s + "\t");
System.out.println();
}
}
//result
인스턴스의 수 : 3
Box Robot Toy
Box Robot Toy
- Set에서 동일한 인스턴스로 판단하는 기준은 무엇일까?
package yoon;
import java.util.HashMap;
import java.util.HashSet;
class Num {
private int num;
public Num(int n) { num = n; }
@Override
public String toString() {
return String.valueOf(num);
}
}
public class HashSetEqualityOne {
public static void main(String[] args) {
HashSet<Num> set = new HashSet<>();
set.add(new Num(7799));
set.add(new Num(9955));
set.add(new Num(7799));
System.out.println("인스턴스의 수 : " + set.size());
for(Num n : set)
System.out.print(n.toString() + "\t");
System.out.println();
}
}
//result
인스턴스의 수 : 3
7799 7799 9955
- 위의 7799는 서로 같은 값을 가지고 있지만, 다른 인스턴스로 바라보기 때문에 출력이 된다.
- Hash<E>이 판단하는 동일 인스턴스의 기준은 Object 클래스에 정의되어있는 두 가지 메소드 호출 근거를 바탕으로 한다.
- public boolean equals(Object obj)
- public int hashCode()
Hash Algorithm & HashMethod
- 다음의 수들을 num % 3연산을 통해 결과를 분류해보자
- 3, 5, 7, 12, 25, 31
- 위의 결과에서 정수5의 존재 여부를 확인하는 방법
- 5 % 3 = 2이므로 연산결과가 0,1은 제외를 시킨다.
- 탐색 1 단계 : 정수5의 해쉬 값을 계산하여 부류결정
- 탐색 2 단계 : 선택된 부류 내에 정수 5가 존재하는지 확인
- 그리고 HashSet을 이용해서 인스턴스의 존재여부 확인
public class HashSetEqualityOne {
public static void main(String[] args) {
HashSet<Num> set = new HashSet<>();
set.add(new Num(7799));
set.add(new Num(9955));
set.add(new Num(7799));
}
}
- hashCode메소드는 인스턴스가 저장된 주솟값을 기반으로 반환값이 만들어진다.
- 인스턴스가 다르면 Object클래스의 hashCode메소드는 다른 값을 반환한다.
- 인스턴스가 다르면 Object클래스의 equals메소드는 false를 반환한다.
- 그러므로 7799를 동일하게 바라보려면 위의 두 메소드를 오버라이딩을 해야한다.
package yoon;
import java.util.HashSet;
class Num {
private int num;
public Num(int n) { num = n; }
@Override
public String toString() {
return String.valueOf(num);
}
@Override
public int hashCode() {
return num % 3; // num의 값이 같으면 부류도 같다.
}
@Override
public boolean equals(Object obj) {
if(num == ((Num)obj).num)
return true;
else
return false;
}
}
public class HashSetEqualityTwo {
public static void main(String[] args) {
HashSet<Num> set = new HashSet<>();
set.add(new Num(7799));
set.add(new Num(9955));
set.add(new Num(7799));
System.out.println("인스턴스 수 : " + set.size());
for(Num n : set)
System.out.print(n + "\t");
System.out.println();
}
}
//result
인스턴스 수 : 2
9955 7799
Written on June 5, 2018