2020. 12. 1. 20:36ㆍJava
- Set
- 순서를 유지하지 않는 데이터의 집합. 데이터의 중복을 허용하지 않는다.
- 인덱스로 요소들을 관리하지 않는다.
예를 들어 나의 판매사이트의 하루 방문자 수(중복 접속을 제외한)를 구하고 싶을때, 126번째 손님이 중복으로 많이 들어올 경우 여러번이 아닌 한번 접속된 걸로 설정해야한다. (Set의 중복 허용 x 성질)
(구현 클래스 : HashSet, TreeSet, LinkedHashSet)
- Set 컬렉션의 공통적인 주요 메서드.
- HashSet
HashSet은 Set인터페이스를 구현한 가장 대표적인 컬렉션이며, 특징대로 중복된 데이터를 저장할 수 없으며 순서를 유지하지 않는다.(자체적인 저장 방식에 따라 순서가 결정)
Set<변수 타입> 객체명 = new HashSet<변수 타입>();
HashSet<변수 타입> 객체명 = new HashSet<변수 타입>();
위 두 문장은 같은 의미 이지만, 되도록이면 맨 위 방법인 Set타입의 참조변수로 선언하는 것을 추천한다. 만일 HashSet을 선언하게되면 추 후 TreeSet과같은 다른 컬렉션으로 바꿔야 한다면 그만큼 문장들을 검토해야할 필요성이 있다. 하지만 Set선언은 HashSet 선언보다 사용할 수 있는 컬렉션의 범위가 넓기 때문이다. (나머지 컬렉션도 동일.)
- HashSet의 사용법과 예제
package bokTest;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetTest {
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("a");
set.add("z");
set.add("c");
set.add("b");
set.add("c"); //중복
set.add("p");
set.add("a"); //중복
set.add("d");
set.add("a"); //중복
//Iterator 생성 방법 (*한번 생성 후 재사용 할경우 재생성 필수)
Iterator<String> iter = set.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
}
}
결과값을 보면 add()를 사용하여 삽입된 요소의 중복이 제거된 형태를 볼 수 있으며, add()순서와 관계없이 데이터가 삽입된것을 알 수 있다. 또한 HashSet의 요소를 불러오기 위하여 Iterator(반복자)를 사용하였다.
but, 서로 다른 객체는 값이 같아도 중복으로 간주하지 않는다. ex)String a = "1"; 과 new Integer(1)은 같은 값으로 저장.
- TreeSet
TreeSet은 이진 검색 트리(binary search tree)라는 자료구조의 형태로 데이터를 저장하는 컬렉션 클래스이다. 중복된 데이터의 저장을 허용하지 않으며 정렬된 위치에 저장하므로 저장순서를 유지하지도 않는다. (이미 오름차순 자동정렬 완성 후 관리)값에 따라 오름차순 정렬 기준(정규식 0-9, A-Z, a-z 순)으로 정렬- TreeSet의 사용법과 예제
package bokTest;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
set.add(80);
set.add(50);
set.add(90);
set.add(10);
set.add(60);
//Iterator 생성 방법 (*한번 생성 후 재사용 할경우 재생성 필수)
Iterator<Integer> iter = set.iterator();
while(iter.hasNext()) { //iter에 다음 읽을 데이터가 있다면
System.out.println(iter.next());
}
}
}
결과값을 보면 add()를 사용한 순서와 관계없이 오름차순으로 자동 정렬되는것을 볼 수 있다. (중복 또한 x)
역순 정렬 가능( NavigableSet descendingSet() )
TreeSet은 이진검색트리 구조(root와 node)이기 때문에 HashSet과는 다르게 추가된 메서드들이 존재한다.
- SortedSet headSet(Object o) : 지정된 객체(데이타)보다 작은 값의 객체들을 반환한다.
- SortedSet tailSet(Object o) : 지정된 객체(데이타)보다 큰 값의 객체들을 반환한다.
- Object pollFirst() : TreeSet의 첫번째 요소(제일 작은 값의 객체)를 반환한다.
- Object pollLast() : TreeSet의 마지막 번째 요소(제일 큰 값의 객체)를 반환한다.
- TreeSet의 이진 검색 트리의 저장과정과 특징
- TreeSet에 사용되는 이진트리는 링크드리스트처럼 여러개의 노드(node)가 서로 연결된 구조로, 각 노드에 최대 2개의 노드를 연결할 수 있으며 '루트(root)'라고 불리는 하나의 노드에서부터 시작해서 계속 확장해나간다.
- 값의 크기를 비교하면서 트리를 따라 내려가고, 작은값은 왼쪽에 큰 값은 오른쪽에 저장.
- 왼쪽 마지막 레벨이 가장 작은 값이 되고 오른쪽 마지막 레벨의 값이 가장 큰 값이 된다.
- 비교에는 TreeSet에 저장되는 객체가 Comparable을 구현하던가 아니면, Comparator를 제공해서 두 객체를 비교할 방법을 알려줘야한다. (TreeSet의 비교 구현 방식)
이진 검색 트리(binary search tree)는
- 모든 노드는 최대 두 개의 자식노드를 가질 수 있다.
- 왼쪽 자식노드의 값은 부모노드의 값보다 작고 오른쪽 자식노드의 값은 부모노드의 값보다 커야한다.
- 노드의 추가 삭제에 시간이 걸린다.(순차적으로 저장하지 않으므로)
- 검색(범위검색)과 정렬에 유리하다.
- 중복된 값은 저장하지 못한다.
- LinkedHashSet
ArrayList와 같이 List인터페이스를 구현한 컬렉션과 달리 HashSet은 저장순서를 유지하지 않는다는 것을 알 수 있었다. 저장순서를 유지하고 관리하고자 한다면 LinkedHashSet을 사용.
package javaTest;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetTest {
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<String>();
set.add("a");
set.add("z");
set.add("c");
set.add("b");
set.add("c"); //중복
set.add("p");
set.add("a"); //중복
set.add("d");
set.add("a"); //중복
//Iterator 생성 방법 (*한번 생성 후 재사용 할경우 재생성 필수)
Iterator<String> iter = set.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
//Collectionx클래스의 sort를 쓰기위하여 Set의 객체들을 list에 담아 정렬.
List<String> list = new LinkedList(set);
Collections.sort(list);
}
}
결과값을 보면 add()된 값 순서로 저장된걸 확인할 수 있다. 중복 또한 제거된 값을 확인할 수 있다.
또한 Set인터페이스의 객체들은 ArrayList 또는 LinkedList에 담을 수 있다.
마지막으로 Set은 일반 배열로 변환 할 수 있다.
타입[] 배열명 = Set명.toArray(new 타입명[Set의 크기]);
public class LinkedHashSetTest {
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<String>();
set.add("a");
set.add("z");
set.add("c");
String arr[] = set.toArray(new String[set.size()]);
for(String i : arr){
System.out.println(i);
}
}
}
출처 : 자바의 정석 2권 Collection
'Java' 카테고리의 다른 글
자바[JAVA] : 추상클래스 (0) | 2021.01.28 |
---|---|
자바[JAVA] : 오버라이딩(Overriding) 이란? (0) | 2021.01.28 |
자바[JAVA] : super 키워드 (0) | 2021.01.28 |
자바[JAVA] : 상속의 특징 (0) | 2021.01.28 |
자바[JAVA]: 제곱과 제곱근(루트) 구하기 Math.pow() // Math.sqrt() (0) | 2020.12.02 |