import java.util.*;
class Ex11_9 {
public static void main(String[] args) {
Object[] objArr = {"1",new Integer(1),"2","2","3","3","4","4","4"};
Set set = new HashSet();
for(int i=0; i < objArr.length; i++) {
set.add(objArr[i]); // HashSet에 objArr의 요소들을 저장
}
// HashSet에 저장된 요소들 출력
System.out.println(set);
// HashSet에 저장된 요소들 출력 (Iterator 이용)
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
* 출력 결과 [1, 1, 2, 3, 4]
* Iterator 사용한 출력 결과 1 1 2 3 4
데이터 저장 순서와 출력 순서가 일치한다는 보장은 없다.
중복된 데이터는 하나의 요소만 남기고 다 제거한다.
문자열 "1"과 Integer 타입의 1은 자료타입이 다르기 때문에 중복된 데이터가 아니다.
예제
HashSet은 객체를 저장하기 전에 기존에 같은 객체가 있는지 확인 (중복을 허용하지 않으니까)
같은 객체가 없으면 저장, 있으면 저장X
boolean add(Object o)는 저장할 객체의 equals()와 hashCode()를 호출
equals()와 hashCode()가 오버라이딩 되어 있어야 함
class ex {
public static void main(String[] args) {
HashSet set = new HashSet();
set.add("abc");
set.add("abc"); // 중복이라 저장 안됨
set.add(new Person("David", 10));
set.add(new Person("David", 10));
System.out.println(set); // [abc, David:10, David:10]
}
}
// equals()와 hashCode()를 오버라이딩해야 HashSet이 바르게 동작
class Person {
String name;
int age;
@Override
public int hashCode() {
// int hash(Object... values); // 선언부, ...: 가변인자
return Objects.hash(name, age);
}
@Override
public boolean equals(Object obj) {
if (! (obj instanceof Person)) return false;
Person p = (Person) obj;
// 나 자신(this)의 이름과 나이를 p와 비교
return this.name.equals(p.name) && this.age == p.age;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + ":" + age;
}
}
예제
합집합, 교집합, 차집합
// A집합, B집합 존재
class ex {
public static void main(String args[]) {
HashSet setA = new HashSet();
HashSet setB = new HashSet();
setA.retainAll(setB); // 교집합. 공통 요소만 남기고 삭제
setA.addAll(setB); // 합집합. setB의 모든 요소를 추가 (SET의 특성상 중복 제외)
setA.removeAll(setB); // 차집합. setB와 공통 요소를 제거
}
}
TreeSet
범위 탐색 (from ~ to), 정렬에 유리
이진 탐색 트리 (binary search tree)로 구현
이진 트리는 모든 노드가 최대 2개의 하위 노드를 갖음 (노드 개수: 0~2개)
각 요소(노드)가 나무 형태로 연결 (LinkedList의 변형)
class TreeNode {
TreeNode left; // 왼쪽 자식노드
Object element; // 저장할 객체
TreeNode right; // 오른쪽 자식노드
}
이진 탐색 트리 (binary search tree)
부모보다 작은 값은 왼쪽, 큰 값은 오른쪽에 저장
단점: 데이터가 많아질수록 데이터 추가, 삭제에 시간이 더 걸림 => 비교 횟수 증가
데이터 저장과정
boolean add(Object o);
HashSet : equals(), hashCode()로 비교
TreeSet : compare()를 호출해서 비교
(* 비교하는 이유 : set은 데이터 중복을 허용하지 않기 때문에 같은 데이터가 있는지 비교해봐야함)
TreeSet의 주요 생성자
TreeSet() : 기본 생성자
저장하는 객체의 Comparable을 사용
TreeSet(Comparator comp) : 주어진 정렬 기준으로 정렬하는 TreeSet을 생성
Comparator : 비교 기준 제공
import java.util.*;
class Ex11_13 {
public static void main(String[] args) {
Set set = new TreeSet(new TestComp()); // 범위 검색, 정렬
set.add(new Test());
set.add(new Test());
set.add(new Test());
set.add(new Test());
set.add(new Test());
System.out.println(set);
}
}
class Test {} // 비교 기준이 없음
class TestComp implements Comparator {
@Override
public int compare(Object o1, Object o2) {
return 0;
// return -1;
}
}
저장되는 객체가 다 같은 객체라고 판단하므로 객체 하나만 출력
TestComp 클래스의 compare 메서드 return 값이 -1일 때, 다 다른 객체라고 판단하므로 각 객체의 주소값 출력