Set
Set 인터페이스를 구현한 모든 Set 컬렉션 클래스는 다음과 같은 특징을 가진다.
1. 요소의 저장 순서를 유지하지 않는다.
2. 같은 요소의 중복 저장을 허용하지 않는다.
대표적인 Set 컬렉션 클래스에 속하는 클래스는 다음과 같다.
1. HashSet<E>
2. TreeSet<E>
HashSet<E> 클래스
HashSet 클래스는 Set 컬렉션 클래스에서 가장 많이 사용되는 클래스 중 하나이다.
JDK 1.2부터 제공된 HashSet 클래스는 해시 알고리즘(hash algorithm)을 사용하여 검색 속도가 매우 빠르다.
HashSet 은 가장 기본적인 Set 컬렉션의 클래스인데, 입력 순서를 보장하지 않고, 순서도 마찬가지로 보장되지 않는다. 그러면 어디에 쓰이냐는 생각이 들 수도 있다.
가장 쉽게 이해할 수 있는 예로는 여러분이 게임에서 '닉네임'을 만든다거나 아이디를 생성할 때 '중복확인'을 눌러 중복된 닉네임 또는 아이디인지 확인하는 것이다. 이는 데이터가 정렬되어있을 필요도 없고, 빠르게 중복되는 값인지만 찾으면 되기 때문에 유용한 방법이 될 수 있다.
좀 더 상세하게 말하자면 hash에 의해 데이터의 위치를 특정시켜 해당 데이터를 빠르게 색인(search)할 수 있게 만든 것이다. 즉, Hash 기능과 Set컬렉션이 합쳐진 것이 HashSet이다. 그렇기 때문에 삽입, 삭제, 색인이 매우 빠른 컬렉션 중 하나다.
TreeSet<E> 클래스
TreeSet 클래스는 데이터가 정렬된 상태로 저장되는 이진 검색 트리(binary search tree)의 형태로 요소를 저장한다.
이진 검색 트리는 데이터를 추가하거나 제거하는 등의 기본 동작 시간이 매우 빠르다.
JDK 1.2부터 제공되는 TreeSet 클래스는 NavigableSet 인터페이스를 기존의 이진 검색 트리의 성능을 향상시킨 레드-블랙 트리(Red-Black tree)로 구현한다.
TreeSet 클래스는 Set 인터페이스를 구현하므로, 요소를 순서에 상관없이 저장하고 중복된 값은 저장하지 않는다.
set 은 인터페이스이기 때문에 new 해서 객체를 생성할 수 없기 때문에 set을 구현한 클래스인 HashSet 을 이용해야 한다.
import java.util.HashSet
import java.util.Set;
public class setExam {
public static void main(String[] args) {
Set<String> set1 = new HashSet<>();
set이 가진 add 메소드는 기본적으로 리턴 값을 boolean 타입으로 갖는다.
따라서 이런 것도 확인 가능하다.
import java.util.HashSet;
import java.util.Set;
public class setExam {
public static void main(String[] args) {
Set<String> set1 = new HashSet<>(); //set 은 인터페이스이기 때문에 new 해서 객체를 생성할 수 없기 때문에 set을 구현한 클래스인 HashSet 을 이용하겠다.
boolean flag1 = set1.add("김철수"); //제네릭을 통해 타입을 강제했기 때문에 String 타입만 add 가능
boolean flag2 = set1.add("이장미");
boolean flag3 = set1.add("김철수");
System.out.println(set1.size()); //size() 를 통해 set 의 크기를 출력
//3개를 저장했지만 "김철수" 가 중복되었기 때문에 2가 출력되는 것을 볼 수 있음
boolean 타입인 flag1, flag2, flag3 에 "김철수"가 중복되는 flag3에는 false가 리턴되는 것을 확인할 수 있다.
set자료구조에서 값에 들어있는 값을 하나씩 꺼내보기 위해서는 Iterator 라는 인터페이스를 이용해야 한다.
따라서 위에서 만든 set1은 iterator라는 메소드를 이용하면 iterator 인터페이스를 구현한 객체가 리턴될 것이다.
import java.util.Iterator;
Iterator<String> iter = set1.iterator(); //set1은 iterator 라는 메소드를 이용하여 Iterator 인터페이스를 구현한 객체 iter 가 리턴
//java.lang 패키지의 클래스는 import 를 하지 않고도 사용할 수 있다.
//그 말인 즉슨 java.lang 패키지가 아니라면 import 해주어야 한다는 뜻이기도 하다.
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class setExam {
public static void main(String[] args) {
Set<String> set1 = new HashSet<>(); //set 은 인터페이스이기 때문에 new 해서 객체를 생성할 수 없기 때문에 set을 구현한 클래스인 HashSet 을 이용하겠다.
set1.add("김철수"); //제네릭을 통해 타입을 강제했기 때문에 String 타입만 add 가능
set1.add("이장미");
set1.add("김철수");
Iterator<String> iter = set1.iterator(); //set1은 iterator 라는 메소드를 이용하여 Iterator 인터페이스를 구현한 객체 iter 가 리턴
while(iter.hasNext()){ //Iterator 안에 있는 hasNext 라는 메소드를 통해 Set 안에 값이 있는 경우에만 while 문 실행
String str = iter.next(); // 값을 꺼내고 다음것을 참조
System.out.println(str); //3명의 이름을 넣었지만 중복값을 제거하고 2명의 이름만 출력
}
}
}
hasNext 메소드는 set안에 값이 있을 때만 true가 반환된다.
따라서 위의 while 문은 set안에 값이 있을 때만 작동된다.
우리는 "김철수", "이장미", "김철수" 이렇게 3명의 이름을 set에 넣었지만 "김철수"가 중복되므로
2명의 이름만 출력되는 것을 확인할 수 있다.
'JAVA' 카테고리의 다른 글
Wrapper Class (래퍼 클래스) (0) | 2021.07.23 |
---|---|
protected 접근제한자 (0) | 2021.07.23 |
접근 제한자와 게터(Getter) 세터(Setter) (0) | 2021.07.19 |
생성자(Constructor) 호출과 정의 (0) | 2021.07.16 |
Thread(쓰레드) (0) | 2021.07.15 |