본문 바로가기
공부 기록

자바에서 HashSet에 값 넣고 꺼내기

by 타태 2025. 8. 10.

 

오늘의 예제는 이렇게 생겼다.

    public static void main(String[] args) {
        final HashSet<String> hashSet = new HashSet<>();
        hashSet.add("key1");
        hashSet.add("key1");
        final Optional<String> first = hashSet.stream().findFirst();
        System.out.println(first.orElse("No elements found"));
        hashSet.remove(0);
    }

 

 

디어셈블링을 해봤으나 HashMap의 예제와 딱히 다를게 없어서 안봐도 될것 같다.

HashSet.java를 확인해 보자.

 

 

HashSet은 java.util 패키지에 위치하며 AbstractSet<E>를 확장하고 Set<E> Cloneable, Serializable을 구현한다.

HashSet은 내부에 HashMap<E,Object>을 두고 인터페이스를 제공한다.

private transient HashMap<E,Object> map; -- HashMap의 key에 HashSet의 요소 저장
private static final Object PRESENT = new Object(); HashMap의 value는 PRESENT라는 더미 객체 (모든 요소에 동일 객체 사용)

public HashSet() {
    map = new HashMap<>();
}
public HashSet(int initialCapacity) {
    map = new HashMap<>(initialCapacity);
}
public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<>(initialCapacity, loadFactor);
}

 

 

  • 기본 초기 용량: 16
  • 기본 부하율(load factor): 0.75
  • 필요 시 초기 용량, 부하율 지정 가능 (HashMap의 특성 그대로 적용)

 

public boolean add(E e) {
    return map.put(e, PRESENT) == null;
}

 

  • HashMap.put(key, value) 호출
    • key: 저장할 요소
    • value: PRESENT (더미 객체)
  • HashMap은 key의 hashCode()스프레딩(spreading)버킷 인덱스 계산 → 저장
  • 이미 동일 key 존재하면 덮어쓰기 → HashSet에서는 중복 저장이 안 되는 이유
public boolean contains(Object o) {
    return map.containsKey(o);
}

 

  • HashMap의 containsKey 그대로 사용 → 해시 기반 검색

 

public boolean remove(Object o) {
    return map.remove(o) == PRESENT;
}

 

  • HashMap에서 key 삭제
  • 해당 key의 버킷 접근 → LinkedList/TreeNode에서 제거

 

정리하자면, HashSet은 사실상 HashMap의 key만 사용하는 래퍼(wrapper)이고 값은 모두 동일한 더미 객체(PRESENT)를 넣어두는 개념이다.

그럼 언제 HashMap을 쓰고 언제 HashSet을 써야할까?

HashSetHashMap의 래퍼(wrapper)라서 연산 과정이 거의 동일하지만, HashSetvalue를 쓰지 않으므로 메모리 사용량이 조금 적고, 값을 처리하는 연산 과정이 조금 더 단순하다. 때문에 중복이 제거 된 값의 집함만 필요할 경우 HashSet을 쓰면 된다.

 

 

Set의 인터페이스를 굳이 사용하지 않겠다면 하나의 값을 정해두고 Key로만 중복을 검사하면서 사용하는것이 얼마든지 가능하기야 하겠지만..?

 

 

참고자료
graalvm-jdk-21

 

 

반응형

댓글