'자바 set 사용법'에 해당되는 글 1건

자바에서 Set은 중복을 허용하지 않는 컬렉션(Collection)이다.

즉, 같은 값을 여러 번 넣으려고 해도 한 번만 저장된다.

Set은 java.util 패키지에 있고, 인터페이스 형태로 존재하며, 다음과 같은 상속 관계를 가지고 있다.

 

 

1. Set의 상속 구조 (인터페이스 중심)

java.lang.Iterable<E>
   ↑
java.util.Collection<E>
   ↑
java.util.Set<E> // 아래는 Set의 구현 클래스들이다.
├── HashSet<E>
│   └── LinkedHashSet<E>
└── SortedSet<E>
     └── NavigableSet<E>
          └── TreeSet<E>

 

2. Set의 대표적인 구현체(클래스)

 

대표적인 구현체로는 다음과 같은 것들이 있다:


2-1. HashSet

  • 가장 많이 사용되는 Set 구현체
  • 내부적으로 HashMap을 사용하여 구현됨
  • 순서를 보장하지 않음
  • null 값을 하나 저장할 수 있음
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");
set.add("apple"); // 중복이므로 무시됨
System.out.println(set); // 출력: [banana, apple] (순서는 보장되지 않음)

2-2. LinkedHashSet

  • HashSet과 거의 같지만, 입력 순서를 유지함
  • 내부적으로 LinkedList + HashMap 구조
Set<String> set = new LinkedHashSet<>();
set.add("apple");
set.add("banana");
set.add("cherry");
System.out.println(set); // 출력: [apple, banana, cherry]

3-3. TreeSet

  • 정렬된 상태로 저장됨
  • 기본은 오름차순 정렬 (또는 Comparator 사용 가능)
  • 내부적으로 Red-Black Tree 구조
Set<Integer> set = new TreeSet<>();
set.add(3);
set.add(1);
set.add(2);
System.out.println(set); // 출력: [1, 2, 3]

 

4.주요 메서드 요약 (Set 인터페이스 공통)


메서드 설명
add(E e) 요소 추가 (중복이면 추가 안 됨)
remove(Object o) 요소 제거
contains(Object o) 포함 여부 확인
size() 크기 확인
clear() 전체 요소 삭제
isEmpty() 비어 있는지 확인
iterator() 반복자 반환 (향상된 for문 사용 가능)

- Collections를 상속 받기에 Collections의 메서드들을 대부분 이용 가능하다.

 

 

5. Set 구현체의 시간 및 공간 복잡도

일전에 코딩 테스트 공부하다가 각 자료구조의 시간복잡도와 공간 복잡도에 대해 찾아본적이 있다.

하여 대표적으로 사용되는 구현체들의 시간복잡도에 대해 적어본다.

 

5-1. HashSet

  • 기반 자료구조: HashMap
  • 해시 함수를 기반으로 하기 때문에 빠름
연산 평균 시간복잡도 최악 시간복잡도
add, remove, contains O(1) O(n)
size, isEmpty O(1) O(1)

최악의 경우는 해시 충돌이 많이 날 때, 내부적으로 연결 리스트나 트리로 변형되면서 느려질 수 있음

  • 공간복잡도: O(n)
    • 요소 저장 외에도 내부적으로 해시 버킷 배열이 필요함

5-2. LinkedHashSet

  • 기반 자료구조: HashMap + LinkedList
  • 입력 순서를 유지하기 위해 연결 리스트 추가됨
연산 평균 시간복잡도 최악 시간복잡도
add, remove, contains O(1) O(n)
  • 공간복잡도: O(n)
    • HashSet보다 약간 더 많은 메모리를 사용 (순서를 기억하는 연결 포인터 때문에)

5-3. TreeSet

  • 기반 자료구조: TreeMap (구체적으로 Red-Black Tree)
  • 정렬이 필요할 때 사용
연산 시간복잡도
add, remove, contains O(log n)
first, last, ceiling, floor O(log n)
  • 공간복잡도: O(n)
    • 균형 트리 구조를 유지하기 위한 포인터들이 추가됨

5-4. 요약

 

구현체 시간복잡도 공간복잡도 특징
HashSet 평균 O(1), 최악 O(n) O(n) 가장 빠름, 순서 없음
LinkedHashSet 평균 O(1), 최악 O(n) O(n) 입력 순서 유지
TreeSet O(log n) O(n) 자동 정렬, 느림
  • 순서 필요 없다 + 빠른 성능 원함 → HashSet
  • 입력 순서 필요 → LinkedHashSet
  • 정렬된 데이터 필요 → TreeSet

6. 언제 사용되는가?

Set은 기본적으로 중복 없이 데이터만 저장하고 싶을 때 쓴다.

Map도 마찬가지로 키의 중복 없이 데이터를 저장을 하지만 값을 중복 없이 저장하지는 않는다.

추가로 Map은 <key,boolean> 형식으로 존재 여부 확인용으로 Set처럼 쓸 수 있지만 메모리 낭비에 가독성도 떨어진다.

 

예시 상황 : 

  • 유저 ID -> 중복 없는 데이터 리스트 만들기
  • 방문한 페이지 집합 관리 
Set<String> visitedPages = new HashSet<>();
visitedPages.add("homePage"); // 홈페이지 방문
visitedPages.add("aboutPage"); // 정보소개 페이지 방문
visitedPages.add("homePage"); // 홈페이지 방문 중복, 무시됨

 

 

7. 다른 구현체로 변환

// Set → List
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");

List<String> list = new ArrayList<>(set);
System.out.println(list); // [banana, apple] — 순서는 보장 안 됨


// List → Set
List<String> list = Arrays.asList("apple", "banana", "apple");
Set<String> setFromList = new HashSet<>(list); // 중복 제거됨


// Set → 배열
Set<String> set = new HashSet<>();
set.add("apple");
set.add("banana");

Object[] arr = set.toArray(); // Object 배열 반환


// 배열 → Set
String[] fruits = {"apple", "banana", "apple"};
Set<String> setFromArray = new HashSet<>(Arrays.asList(fruits));
블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,