C#

Dictionary vs HashSet – 비슷해 보이지만 목적이 다르다

Juan_ 2025. 6. 8. 20:37
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