Java 의 HashMap & HashSet 개념 정리

scminy0527·2026년 2월 27일
post-thumbnail

— 해시 기반 컬렉션의 핵심 이해하기

자바에서 데이터를 다루다 보면
배열, ArrayList 다음 단계에서 반드시 만나게 되는 컬렉션이 있다.

바로 HashMap 과 HashSet 이다.

처음에는 그냥 “중복 안되는 자료구조”,
“Key-Value 형태” 정도로 외웠지만,
직접 사용해보니 구조적으로 이해하는 게 훨씬 중요하다는 걸 느꼈다.


1. HashMap 이란?

HashMap<String, Integer> map = new HashMap<>();

HashMap은

🔑 Key : Value 형태로 데이터를 저장하는 컬렉션

특징

  • Key는 중복 불가
  • Value는 중복 가능
  • 저장 순서 보장 ❌
  • 검색 속도 매우 빠름 (평균 O(1))

🔹 put()의 동작 원리

map.put("student1", 80);
  • 해당 key가 없다 → 새로 추가
  • 해당 key가 있다 → value 덮어쓰기

즉, key가 기준이다.


🔹 내부 구조 (개념적 이해)

HashMap은 내부적으로

해시 함수 → 버킷(bucket) → 연결 구조

형태로 저장된다.

Key의 hashCode() 값을 이용해 저장 위치를 빠르게 찾는다.

그래서 인덱스 접근은 없지만
검색이 매우 빠르다.


2. HashMap 순회 방법

① entrySet() 사용 (가장 권장)

for(Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

✔ key와 value를 동시에 접근 가능
✔ 가장 효율적


② Iterator 사용

Iterator<Map.Entry<String, Integer>> iter = map.entrySet().iterator();

while(iter.hasNext()) {
    Map.Entry<String, Integer> entry = iter.next();
    System.out.println(entry.getValue());
}

Iterator는

다음 객체가 있는지 확인 → 다음 객체로 이동

하는 구조다.

⚠ next()는 "값 반환 + 포인터 이동"이 동시에 일어나므로
반복문 안에서 한 번만 호출해야 한다.


왜 Iterator가 필요할까?

반복 중 삭제를 할 때 필요하다.

Iterator<Map.Entry<String, Integer>> iter = map.entrySet().iterator();

while(iter.hasNext()) {
    Map.Entry<String, Integer> entry = iter.next();

    if(entry.getValue() < 60) {
        iter.remove(); // 안전한 삭제
    }
}

for-each 중에 map.remove()를 사용하면
ConcurrentModificationException 이 발생한다.


3. HashSet 이란?

HashSet<String> set = new HashSet<>();

HashSet은

중복을 허용하지 않는 자료구조

특징

  • 중복 제거에 특화
  • 순서 보장 ❌
  • 검색 속도 빠름 (평균 O(1))

🔹 중복 제거 예시

ArrayList<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");
list.add("apple");

HashSet<String> set = new HashSet<>(list);

System.out.println(set);
// [apple, banana]

자동으로 중복 제거됨.


4. HashMap vs HashSet 차이

구분HashMapHashSet
저장 형태Key-ValueValue
중복 기준KeyValue
순서없음없음
검색 속도빠름빠름

5. 구조적으로 보면

사실 HashSet은 내부적으로

HashMap을 기반으로 구현되어 있다.

즉,

HashSet<String>

은 내부적으로

HashMap<String, Object>

형태로 동작한다.

Value는 의미 없는 더미 객체다.

그래서 해시 기반 구조는 동일하다.


6. 언제 사용하면 좋을까?

✔ 빠른 검색이 필요할 때
✔ 중복 제거가 필요할 때
✔ 순서가 중요하지 않을 때


정리

  • HashMap은 Key 기준 관리
  • HashSet은 중복 제거에 특화
  • entrySet()은 key-value 묶음 반환
  • Iterator는 포인터 이동 개념
  • next()는 한 번만 호출해야 함
  • 반복 중 삭제는 Iterator.remove() 사용

개인적으로 느낀 점

배열 → ArrayList → Set/Map

으로 오면서 느낀 건

인덱스 기반 사고에서
"해시 기반 사고"로 전환되는 지점이라는 것

이걸 이해하면
자료구조의 절반은 넘어가는 것 같다.

profile
비전공자에서 시작해 Flutter로 실서비스를 만들었고, 더 깊은 개발을 향해 계속 성장 중인 개발자

0개의 댓글