
Java Collection Framework 중 하나로, 중복을 허용하지 않는 데이터 저장 구조
내부적으로 HashMap을 사용한다.
주요 특징: 순서 없음, 중복 없음, 빠른 탐색
Set<String> set = new HashSet<>();
중복 제거가 필요할 때
빠른 탐색이 필요할 때 (시간복잡도 O(1))
리스트보다 존재 여부 체크가 더 중요할 때
🧐 왜 HashSet을 사용하면 빠를까?
1. 탐색 시간
일반적인 배열에서는 값을 찾기 위해 앞에서부터 끝까지 일일이 비교해야 함 →O(n)
HashSet은 내부적으로 해시함수를 통해 값을 저장하고 조회하기 때문에 →O(1)set.contains(값);
contains()로 해당 값이 set에 있는지를 거의 즉시 확인할 수 있다.
2. 삽입 시간
HashSet에 값을 넣는 것도 해시를 기반으로 하기 때문에 일반적으로O(1)set.add(값);즉, n개의 원소를
HashSet에 넣는 데O(n),
m개의 원소를 각각 탐색하는 데O(m)→ 총O(n + m)
import java.util.*;
public class HashSetExample {
public static void main(String[] args) {
Set<String> fruits = new HashSet<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Apple"); // 중복, 저장되지 않음
System.out.println(fruits); // [Apple, Banana] 순서 보장 안 됨
System.out.println(fruits.contains("Banana")); // true
}
}
| 항목 | HashSet | ArrayList |
|---|---|---|
| 중복 허용 | ❌ 허용하지 않음 | ✅ 허용함 |
| 순서 유지 | ❌ 순서 보장 안 됨 | ✅ 입력 순서 유지 |
| 탐색 시간 | ✅ O(1) (빠름) | ❌ O(n) (느림) |
| 인덱스로 접근 | ❌ 불가능 | ✅ 가능 (get(index)) |
| 주요 목적 | 중복 제거 / 포함 여부 확인 | 순서 유지 / 순차적 데이터 처리 |
활용 예: 배열 중복 제거
int[] arr = {1, 2, 2, 3, 4, 4}; Set<Integer> unique = new HashSet<>(); for (int num : arr) { unique.add(num); } System.out.println(unique); // [1, 2, 3, 4]
HashSet은 순서를 유지하지 않는다 → 출력 순서에 의존하면 안 됨😵💫 오해하기 쉬운 점
"Apple → Banana → Cherry"를 넣었으니 이 순서대로 출력될 거야!
❌HashSet은 입력 순서가 아닌 해시값 기준으로 저장됨. 출력 순서는 예측 불가.
📌 예제
Set<String> set = new HashSet<>();
set.add("Apple");
set.add("Banana");
set.add("Cherry");
System.out.println(set); // 출력 예: [Banana, Cherry, Apple]
✅ 해결 방법이 필요하면?
순서를 유지하고 싶다면 LinkedHashSet 사용
contains()는 빠르지만, get(index)는 불가능함😵💫 오해하기 쉬운 점
set.get(1)하면 두 번째 값이 나올 줄 알았는데?
❌HashSet은 인덱스를 기반으로 값을 꺼낼 수 없음. 순서도 없고, 인덱스도 없음.
📌 잘못된 코드
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
// 오류 발생!
String s = set.get(1); // ❌ get()은 존재하지 않음
✅ 해결 방법이 필요하면?
인덱스 접근이 필요하면 ArrayList를 사용하거나 Set을 리스트로 변환
List<String> list = new ArrayList<>(set);
System.out.println(list.get(1));
HashSet은 내부적으로 HashMap<K, Object>로 구현됨😵💫 오해하기 쉬운 점
"contains로 찾았으니 몇 번째에 있는지도 알 수 있겠지?"
❌HashSet은 값이 존재하는지 여부만 확인 가능. 인덱스 위치는 알 수 없음.
📌 예제
Set<Integer> set = new HashSet<>();
set.add(10);
set.add(20);
System.out.println(set.contains(20)); // ✅ true
// set.indexOf(20); // ❌ 불가능, 메서드 없음
😵💫 오해하기 쉬운 점
"null은 예외 터질 것 같은데?"
❌HashSet은null값을 1개까지 저장 가능
📌 예제
Set<String> set = new HashSet<>();
set.add(null);
set.add(null); // 중복이므로 저장 안 됨
System.out.println(set); // [null]
HashSet은 빠르고 효율적인 중복 제거 및 탐색용 컬렉션
내부 구조는 해시 기반, 순서 없음
실무에서 자주 쓰이며, 특히 브루트포스 최적화, 중복 제거 등에서 유용