저번 글에서는 Map에 대해 알아봤고, 이번에는 Set에 대해 정리해본다.
Set은 중복을 허용하지 않는 컬렉션이다. List와 달리 인덱스 개념이 없으며, 같은 값은 한 번만 저장된다. 따라서 Set의 핵심은 값을 “어떻게 저장하느냐”가 아니라, “이미 존재하는 값인지 여부를 판단하는 것”에 있다.
Set에는 두 가지 중요한 규칙이 있다.
첫째, 중복된 요소는 저장될 수 없다.
둘째, 요소의 동일성은 equals()와 hashCode()를 기준으로 판단한다.
이 때문에 Set에 값을 추가할 때는 내부적으로 “이 값이 이미 존재하는가?”를 먼저 검사하며, 이미 존재하는 값이라면 아무 일도 일어나지 않는다.
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(1);
set.add(2);
// 결과: [1, 2]
Map과 비교하면 Set의 구조가 더 명확해진다. Map은 Key–Value 쌍(Entry)을 저장하는 반면, Set은 값 하나만 저장한다. 구조적으로 보면 Map은 Entry(Key + Value)의 집합이고, Set은 Value 하나의 집합이라고 이해할 수 있다. 실제로 HashSet은 내부적으로 HashMap의 Key만 사용하는 구조로 구현되어 있으며, 이런 이유로 Set을 “Value가 없는 Map”이라고 생각해도 크게 틀리지 않는다.
Set의 대표적인 구현체는 HashSet이다. HashSet은 순서를 보장하지 않지만, 빠른 중복 검사(contains)에 특화되어 있다. 그래서 Set은 중복 검증, 유일성 보장, 이미 처리한 데이터인지 확인하는 상황에 가장 잘 어울린다.
예를 들어 로또 번호 검증에서는 List보다 Set을 사용하는 것이 훨씬 자연스럽다.
List<Integer> lottoNumbers;
Set<Integer> numbers = new HashSet<>(lottoNumbers);
if (numbers.size() != 6) {
throw new IllegalArgumentException("중복된 번호가 있습니다.");
}
여기서 한 가지 포인트는, List로 받은 lottoNumbers를 그대로 HashSet 생성자에 전달했다는 것이다. 이는 HashSet이 생성자에서 Collection 타입을 받도록 설계되어 있기 때문에 가능하다. 내부적으로는 전달받은 컬렉션의 요소를 하나씩 add하면서 Set의 규칙에 따라 중복을 자동으로 제거한다.
결과적으로 이 한 줄의 코드는
“List에 들어 있는 값들 중 중복을 제거해 Set으로 변환한다” 라는 의도를 가장 간결하게 표현한 방식이라고 볼 수 있다.
'Java' 카테고리의 다른 글
| Java에서 Map/Set/Hash가 헷갈린다…(3) (1) | 2026.01.06 |
|---|---|
| Java에서 Map/Set/Hash가 헷갈린다…(1) (0) | 2026.01.06 |
| Java Pattern / Matcher 정리 (0) | 2025.12.29 |
