728x90
Dictionary vs HashSet – 비슷해 보이지만 목적이 다르다
개발하면서 이런 컬렉션들 자주 본다.
var dict = new Dictionary<string, int>();
var set = new HashSet<string>();
둘 다 뭔가 Add()
, Contains()
같은 메서드를 제공하고, 키 기반으로 쓰는 것처럼 보인다.
그러다 보면 이런 의문이 생긴다.
"둘 다 검색 빠르다며? 그럼 뭐가 다르고 왜 둘 다 있어야 해?"
이번 챕터에선 Dictionary와 HashSet의 근본적인 차이와, 실무에서 어떤 상황에 어떤 걸 써야 할지 정확히 구분해보자.
문제 상황: 키만 쓰고 싶은데 Dictionary까지 써야 할까?
var tags = new Dictionary<string, bool>();
tags["csharp"] = true;
if (tags.ContainsKey("csharp"))
{
Console.WriteLine("태그 있음");
}
이런 코드는 사실상 값 없이 키만 사용하는 Dictionary다.
그럼 HashSet을 쓰는 게 더 낫지 않을까?
Dictionary – Key/Value 쌍을 관리하는 해시 테이블
var scores = new Dictionary<string, int>();
scores["Alice"] = 90;
scores["Bob"] = 85;
- Key로 빠르게 검색 가능 (O(1))
- Key는 고유(unique)해야 함
- 값(Value)이 필요할 때 사용
목적: "이 키에 대응되는 값을 저장하고 싶다"
HashSet – 중복 없는 값의 모음
var visitedPages = new HashSet<string>();
visitedPages.Add("home");
visitedPages.Add("about");
visitedPages.Add("home"); // 중복 무시됨
- 값 자체가 곧 Key다 (Value 없음)
- 중복 자동 제거
- 빠른 존재 여부 체크 (O(1))
목적: "이 값이 존재하는지 여부만 알고 싶다"
내부 구조는 비슷하다
두 자료구조 모두 Hash 기반으로 구현되어 있다.
즉, 둘 다 평균적으로 탐색/삽입/삭제가 빠르다 (O(1))
그런데 Dictionary는 다음처럼 구성된다:
Key → Value
"홍길동" → 90
반면 HashSet은 아래처럼 Key만 관리한다:
"home"
"about"
그래서 HashSet은 Dictionary보다 더 가볍고 빠르다.
(값을 저장/관리할 필요가 없기 때문)
실무 예시: 방문 기록 관리
// Dictionary 방식
var visited = new Dictionary<string, bool>();
visited["/home"] = true;
if (visited.ContainsKey("/home"))
Console.WriteLine("이미 방문");
// HashSet 방식
var visited = new HashSet<string>();
visited.Add("/home");
if (visited.Contains("/home"))
Console.WriteLine("이미 방문");
값이 필요 없다면 HashSet이 더 직관적이고 효율적이다.
언제 어떤 걸 써야 할까?
상황 | Dictionary | HashSet |
---|---|---|
Key-Value 저장 | ✅ 필요함 | ❌ 필요 없음 |
중복 제거 | 간접적으로 가능 | 자동 처리됨 |
빠른 검색 | 가능 | 가능 (조금 더 빠름) |
구현 구조 | Key → Value | Key만 저장 (Set) |
용도 | 학생 이름 → 점수, 상품 코드 → 가격 | 방문한 URL 목록, 중복 제거 대상 리스트 |
마무리하며
Dictionary와 HashSet은 겉으론 비슷해 보여도, 설계 철학과 목적이 다르다.
- 키에 대응되는 값이 필요하다 → Dictionary
- 존재 여부만 확인하거나 중복 제거가 목적이다 → HashSet
괜히 Dictionary를 bool 값으로 채우면서 쓰지 말고,
진짜 의도에 맞는 자료구조를 골라서 쓰자.
그게 성능도, 코드도, 유지보수도 다 좋다.
728x90
'C#' 카테고리의 다른 글
async vs await – 비동기 코딩, 진짜 이해하고 쓰고 있나? (29) | 2025.06.07 |
---|---|
Nullable과 null 처리 전략 – null 때문에 또 터졌다고? (47) | 2025.06.06 |
object vs dynamic vs var – 언제 뭘 써야 헷갈리지 않을까? (3) | 2025.06.06 |
값 타입 vs 참조 타입 – 구조체와 클래스, 뭐가 다른데? (22) | 2025.06.05 |
ref, out, in - C# 파라미터 키워드 제대로 구분하자 (18) | 2025.06.04 |