`Set`은 집합을 나타내는 자료구조입니다. 집합은 중복된 원소가 없고 원소들 간에 순서가 중요하지 않은 데이터 구조입니다. `Set`은 기본적으로 중복을 허용하지 않으며, 각 원소가 한 번만 존재하도록 보장합니다.
Set의 특징:
1. 중복 허용하지 않음: `Set`에 값을 추가할 때 이미 존재하는 값은 추가되지 않습니다.
2. 순서 없음: `Set`은 원소의 순서를 보장하지 않으며, 일반적으로 `HashSet`과 같은 구현체는 내부적으로 순서에 상관없이 원소를 저장합니다.
3. 자동 정렬이 없음: `HashSet`은 정렬되지 않지만, `TreeSet`은 원소들을 자동으로 오름차순으로 정렬하여 저장합니다.
4. 효율적인 검색: `Set`의 주요 특징 중 하나는 중복 원소를 자동으로 제거하고 검색, 추가, 삭제 작업이 빠르다는 것입니다. 특히 `HashSet`은 내부적으로 해시 테이블을 사용하여 빠른 검색 성능을 제공합니다.
Set 인터페이스를 구현한 주요 클래스들:
- `HashSet`: 가장 일반적인 `Set` 구현체로, 순서를 보장하지 않으며(출력 결과가 항상 동일하지 않을 수 있음), 빠른 검색과 추가가 가능합니다.
- `LinkedHashSet`: `HashSet`과 비슷하지만, 삽입 순서를 유지합니다.
- `TreeSet`: `Set` 인터페이스를 구현한 클래스 중 하나로, 원소들을 자동으로 정렬하여 저장합니다. 기본적으로 오름차순으로 정렬됩니다.
1. HashSet 사용 예시
import java.util.;
public class HashSetExample {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
// 원소 추가
set.add("apple");
set.add("banana");
set.add("cherry");
set.add("apple"); // 중복된 원소는 추가되지 않음
// 원소 출력
System.out.println("Set: " + set);
// 원소 존재 여부 확인
if (set.contains("banana")) {
System.out.println("Set contains banana");
}
// 원소 제거
set.remove("cherry");
System.out.println("Set after removal: " + set);
// Set의 크기
System.out.println("Set size: " + set.size());
// Set 비우기
set.clear();
System.out.println("Set after clearing: " + set);
}
}
출력 결과:
Set: [banana, apple, cherry]
Set contains banana
Set after removal: [banana, apple]
Set size: 2
Set after clearing: []
- `add()`: `Set`에 원소를 추가합니다. 중복된 값은 자동으로 추가되지 않습니다.
- `contains()`: `Set`에 특정 원소가 포함되어 있는지 확인합니다.
- `remove()`: `Set`에서 특정 원소를 제거합니다.
- `size()`: `Set`에 포함된 원소의 개수를 반환합니다.
- `clear()`: `Set`에 포함된 모든 원소를 제거합니다.
2. LinkedHashSet 사용 예시
import java.util.;
public class LinkedHashSetExample {
public static void main(String[] args) {
Set<String> set = new LinkedHashSet<>();
set.add("apple");
set.add("banana");
set.add("cherry");
set.add("apple"); // 중복된 원소는 추가되지 않음
System.out.println("LinkedHashSet: " + set);
}
}
출력 결과:
LinkedHashSet: [apple, banana, cherry]
3. TreeSet 사용 예시
import java.util.;
public class TreeSetExample {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<>();
set.add(5);
set.add(1);
set.add(3);
set.add(2);
set.add(4);
System.out.println("TreeSet: " + set);
}
}
출력 결과:
TreeSet: [1, 2, 3, 4, 5]
- `TreeSet`은 원소들을 자연스럽게 오름차순으로 정렬하여 저장합니다. 만약 내림차순으로 정렬하고 싶다면, `Comparator`를 사용하여 정렬 순서를 지정할 수 있습니다.
Set을 사용할 때의 장점
1. 중복 제거: `Set`은 원소가 중복되는 것을 자동으로 방지합니다. 즉, 데이터를 집합 형태로 저장하고 싶을 때 유용합니다.
2. 빠른 검색과 삭제: 해시 기반의 구현체인 `HashSet`을 사용하면, 원소를 검색하거나 삭제하는 데 시간이 효율적입니다 (대부분 O(1)의 시간 복잡도를 가집니다).
3. 순서 보장: `LinkedHashSet`이나 `TreeSet`을 사용하면 원소들의 순서를 보장할 수 있습니다.
Set을 사용할 때의 주의사항
1. 순서가 중요하지 않은 경우: 기본적으로 `HashSet`은 원소의 삽입 순서를 보장하지 않으므로, 삽입된 순서가 중요한 경우에는 `LinkedHashSet`을 사용해야 합니다.
2. 정렬: `TreeSet`은 원소들을 자연스러운 순서대로 정렬하므로, 특정한 정렬 순서를 원할 경우 `Comparator`를 사용하여 순서를 지정할 수 있습니다.
Set과 List의 차이점
| 구분 | Set | List |
| 중복 허용 여부 | 중복 원소를 허용하지 않음 | 중복 원소를 허용 |
| 순서 보장 여부 | 순서가 보장되지 않음 (`HashSet`) | 삽입 순서를 보장 (`ArrayList`, `LinkedList`) |
| 검색 성능 | 평균적으로 빠름 (O(1)) | 원소를 찾는데 O(n)의 시간이 걸릴 수 있음 |
| 주요 용도 | 집합을 표현할 때, 중복 없는 원소만 필요할 때 | 순서를 유지하며 원소를 저장하고 접근할 때 |
결론
- Set은 중복을 허용하지 않는 집합 자료구조입니다. 집합의 주요 특징은 중복된 원소를 자동으로 제거하며, 순서가 중요하지 않다는 점입니다.
- 자바에서 제공하는 `Set` 인터페이스의 구현체들은 `HashSet`, `LinkedHashSet`, `TreeSet` 등이 있으며, 각각 중복 허용 안 함, 삽입 순서 유지, 정렬된 순서 저장을 제공합니다.