울음참고 개발공부
728x90

 

 

HashMap과 Hashtable의 차이

 

 

HashMap 과 Hashtable
모두 자바에서 사용되는 해시 맵(Hash Map)자료 구조이다.
기능적으로 유사하지만 어떤 차이가 있는지 살펴보자

 

 

 

1. 동기화(synchronization)

 

  • Hashtable
    • 동기화된 메소드를 통해 스레드 안전(thread-safe)을 제공
    • 여러 스레드가 동시에 Hashtable에 접근하더라도 안전하게 사용할 수 있음
  • HashMap
    • 동기화를 제공하지 않음
    • 여러 스레드가 동시에 HashMap에 접근할 경우 외부에서 동기화를 수행해야 함

 

 

 

2. null 허용

 

  • Hashtable 
    • 키와 값으로 null 을 허용하지 않음
    • null 값을 가진 키 또는 값을 저장하려면 NullPointException 발생
  • HashMap
    • null 을 값이나 키로 사용할 수 있음
    • null 값을 가진 키 또는 값이 허용되므로 주의가 필요함

 

 

3.  속도

 

  • 일반적으로 HashMap은 Hashtable 보다 더 빠름
    • HashMap - 동기화 메커니즘을 가지지 않기 때문에 비동기적인 성능을 제공
    • Hashtable - 동기화를 지원하므로 스레드 안정성을 유지하기 위해 동기화 관련 작업을 수행해야 하므로 선능이 떨어질 수 있음 

 

상황에 따른 사용
HashMap - 단일 스레드 환경, null 허용이 필요한 경우
Hashtable - 멀티스레드 환경이거나 동기화가 필요한 경우

 

 


 

 

 

각각 어떤 상황에서 HashMap과 TreeMap을 선택하나요?

 

 

HashMap과 TreeMap은 둘 다 자바에서 사용되는 맵(Map) 자료 구조입니다.
그러나 두 자료 구조 사이에는 몇 가지 차이점이 있으며, 선택하는 상황은 다음과 같이 달라집니다:

 

 

 

HashMap

 

  • 해시 맵으로 구현되어 있으며, 해시 함수를 사용하여 요소를 저장하고 검색
  • 키와 값을 기반으로 매핑된 데이터를 저장
  • 데이터의 순서가 보장되지 않음.요소들의 순서는 해시 함수와 내부 버킷 구조에 의해 결정됨
  • 빠른 데이터 삽입,삭제,조회 연산이 필요한 경우 유용
  • 정렬이 필요하지 않거나 데이터의 순서에 관계없이 빠른 접근이 중요한 상황에 적합
    • 예 ) 데이터베이스에서 키-값 쌍을 캐싱하거나 빠른 데이터 조회를 요구하는 애플리케이션에서 사용

 

 

TreeMap

 

  • 이진 검색 트리(Binary Search Tree)로 구현되어 있으며, 키를 기준으로 정렬된 상태로 요소를 저장  
  • 데이터가 정렬된 순서로 유지되므로 검색과 범위 쿼리(range query)에 효과적임
  • 데이터의 추가,삭제, 조회 연산에 시간이 더 걸릴 수 있음
  • 키의 정렬이 필요한 상황에 적합
    • 예 ) 정렬된 데이터 집합을 유지하고 필요한 범위의 데이터를 효율적으로 검색하는 경우 
  • 정렬된 맵을 순회하거나 범위 쿼리를 수행해야하는 상황에 유용 

 

HashMap vs TreeMap
데이터의 순서가 중요하지 않고 빠른 접근이 필요한 경우 -> HashMap
데이터를 정렬된 상태로 유지하고 정렬된 순서로 데이터에 접근해야 하는 경우 -> TreeMap

 

 


 

 

 

HashMap 과 HashSet 의 구현 원칙 

 

 

 

 

HashMap 의 구현 원칙

 

 

1. 해시 함수 사용:

HashMap은 해시 함수를 사용하여 키를 해시 코드로 변환하고, 이를 내부 배열의 인덱스로 매핑합니다.

이를 통해 키-값 쌍이 저장되는 버킷(bucket)을 결정합니다.

 

2. 동등성 비교:

HashMap은 동일한 키를 가진 요소를 구별하기 위해 동등성 비교를 수행합니다.

동등성 비교는 키의 equals() 메소드를 사용하여 이루어집니다.

동등성 비교 결과가 동일한 키는 같은 버킷에 저장되며, 기존의 요소와 중복되는 경우 값을 덮어씁니다.

 

3. 충돌 처리:

해시 함수로 생성된 해시 코드가 동일한 경우 충돌이 발생합니다.

HashMap은 충돌을 처리하기 위해 각 버킷에 연결 리스트 형태로 요소를 저장합니다.

동일한 버킷에 충돌이 발생하면 연결 리스트에 새로운 요소를 추가하고, 탐색 시에는 동일한 버킷의 연결 리스트를 순회하여 원하는 요소를 찾습니다.

 

4. 초기 용량 및 로드 팩터:

HashMap은 초기 용량(initial capacity)과 로드 팩터(load factor)를 가지고 있습니다.

초기 용량은 HashMap이 초기화될 때 버킷 배열의 크기를 결정합니다.

로드 팩터는 해시 테이블의 총 요소 수와 버킷 배열의 크기 비율을 의미하며, 기본값은 0.75입니다.

로드 팩터를 기준으로 HashMap은 자동으로 크기를 조정하여 적절한 성능을 유지합니다.

 

5. 순서 보장하지 않음:

HashMap은 요소들의 순서를 보장하지 않습니다.

해시 함수와 버킷 구조에 의해 요소들이 저장되며, 저장 순서와 접근 순서는 다를 수 있습니다.

 

6. 동기화 지원:

HashMap은 기본적으로 스레드 간 안전하지 않습니다.

멀티스레드 환경에서 동기화가 필요한 경우 ConcurrentHashMap과 같은 동기화된 버전을 사용하는 것이 좋습니다.

 

 

 

 

 

HashSet 의 구현 원칙

 

 

1. 해시 함수와 해시 코드:

HashSet은 해시 함수를 사용하여 요소의 해시 코드를 생성합니다. 이를 통해 요소가 내부 배열의 인덱스로 매핑됩니다.

해시 함수는 요소의 hashCode() 메소드를 호출하여 해시 코드를 얻습니다.

 

2. 동등성 비교:

HashSet은 요소의 동등성 비교를 수행하여 중복을 방지합니다. 동등성 비교는 요소의 equals() 메소드를 사용합니다.

동등성 비교 결과가 동일한 요소는 동일한 버킷에 저장되지 않습니다.

 

3. 충돌 처리:

HashSet은 충돌이 발생할 경우 연결 리스트 형태로 요소를 저장합니다.

동일한 버킷에 충돌이 발생하면 연결 리스트에 새로운 요소를 추가하고, 탐색 시에는 동일한 버킷의 연결 리스트를 순회하여 원하는 요소를 찾습니다.

 

4. 초기 용량 및 로드 팩터:

HashSet은 초기 용량과 로드 팩터를 가지고 있습니다.

초기 용량은 HashSet이 초기화될 때 내부 배열의 크기를 결정합니다.

로드 팩터는 해시 테이블의 총 요소 수와 버킷 배열의 크기 비율을 의미하며, 기본값은 0.75입니다.

로드 팩터를 기준으로 HashSet은 자동으로 크기를 조정하여 적절한 성능을 유지합니다.

 

5. 순서 보장하지 않음:

HashSet은 요소들의 순서를 보장하지 않습니다.

해시 함수와 버킷 구조에 의해 요소들이 저장되며, 저장 순서와 접근 순서는 다를 수 있습니다.

 

6. 동기화 지원하지 않음:

HashSet은 기본적으로 스레드 간 안전하지 않습니다.

멀티스레드 환경에서 동기화가 필요한 경우 ConcurrentHashSet과 같은 동기화된 버전을 사용하는 것이 좋습니다.

 

 

 

HashSet은 중복을 허용하지 않는 고성능의 자료 구조로 사용되며, 내부적으로는 HashMap을 기반으로 구현됩니다.
import java.util.HashSet;

public class HashSetExample {
    public static void main(String[] args) {
        // HashSet 생성
        HashSet<String> hashSet = new HashSet<>();

        // 요소 추가
        hashSet.add("사과");
        hashSet.add("바나나");
        hashSet.add("딸기");
        hashSet.add("바나나"); // 중복된 요소는 추가되지 않음

        // 요소 개수 확인
        System.out.println("HashSet 크기: " + hashSet.size());  // 출력: 3

        // 요소 포함 여부 확인
        boolean containsBanana = hashSet.contains("바나나");
        System.out.println("바나나 포함 여부: " + containsBanana);  // 출력: true

        // 요소 제거
        hashSet.remove("딸기");

        // 모든 요소 순회
        System.out.println("HashSet 요소:");
        for (String item : hashSet) {
            System.out.println(item);
        }
    }
}

 

728x90
profile

울음참고 개발공부

@메각이

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!