Set
📚참고
컬렉션 프레임워크와 핵심 인터페이스
Set
- 순서X, 중복X (List와 반대)
- HashSet
- Set 인터페이스를 구현한 대표적인 컬렉션 클래스
- 순서를 유지하려면 LinkedHashSet 클래스를 사용하면 된다.
- TreeSet
- 범위 검색(ex. 10~20 사이의 수)과 정렬에 유리한 컬렉션 클래스
- HashSet 보다 데이터 추가, 삭제할 때 시간이 더 걸린다.
HashSet
예제
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;
}
}
TreeSet 범위검색에 유용한 메서드
- subSet() : 범위검색의 결과를 반환 (from ~ to)
- headSet() : 지정된 객체보다 작은 값의 객체들을 반환
- tailSet() : 지정된 객체보다 큰 값의 객체들을 반환
트리 순회 (tree traversal)
- 이진 트리의 모든 노드를 한번씩 읽는 것
- 전위순회 (preorder)
- 중위순회 (inorder) : 오름차순으로 정렬된다.
- 후위순회 (postorder)
- 레벨순회
'JAVA > 컬렉션 프레임워크' 카테고리의 다른 글
Comparator & Comparable (0) | 2021.06.01 |
---|---|
Arrays (0) | 2021.05.31 |
Iterator (0) | 2021.05.18 |
LinkedList (0) | 2021.05.04 |
컬렉션 프레임워크 (Collection Framework) (0) | 2021.05.02 |
댓글
이 글 공유하기
다른 글
-
Comparator & Comparable
Comparator & Comparable
2021.06.01 -
Arrays
Arrays
2021.05.31 -
Iterator
Iterator
2021.05.18 -
LinkedList
LinkedList
2021.05.04