HashMap과 Hashtable의 차이점은 무엇입니까?


3749

Java HashMap와 a 의 차이점은 무엇입니까 Hashtable?

스레드되지 않은 응용 프로그램에 더 효과적인 것은 무엇입니까?


17
HashTable은 Java 1.7에서 더 이상 사용되지 않으며 ConcurrentMap 구현
MissFiona

@MissFiona 아니, ConcurrentMap이다 없는 질문은 스레딩 / 동시성을 의미하는 "비 스레드 응용 프로그램은"문제가되지 않습니다 말한대로, 여기에 필요.
Basil Bourque

답변:


3773

Java HashMapHashtableJava 에는 몇 가지 차이점이 있습니다 .

  1. Hashtable되고 동기화 반면 HashMap아니다. 이 차종 HashMap보다 비 스레드 응용 프로그램을위한, 동기화 객체는 일반적으로 더 나은 동기화 것보다 수행한다.

  2. Hashtablenull키나 값을 허용하지 않습니다 . HashMap하나의 null키와 여러 null값을 허용 합니다.

  3. 의 HashMap의 서브 클래스 중 하나입니다 LinkedHashMap그래서 당신은 (기본적으로 삽입 순서입니다) 예측 가능한 반복 순서를 싶어하는 경우에, 당신은 쉽게를 교환 할 수있는 HashMap경우 a LinkedHashMap. 를 사용하는 경우 쉽지 않습니다 Hashtable.

동기화는 문제가되지 않기 때문에 권장 HashMap합니다. 동기화가 문제가되면을 참조하십시오 ConcurrentHashMap.


84
HashMap을 스레드로부터 안전하게하려면을 사용하십시오 Collections.synchronizedMap().
Rok Strniša

275
또한 스레드 안전성에 대한 순진한 접근 방식 Hashtable( "모든 방법을 동기화하면 동시성 문제를 처리해야합니다!")이 스레드 응용 프로그램의 경우 훨씬 더 나빠 집니다. 외부 동기화 HashMap(및 결과에 대한 생각) 또는 ConcurrentMap구현 사용 (확장 성을 위해 확장 API 활용)이 더 좋습니다. 결론 : 사용하는 유일한 이유 Hashtable는 레거시 API (1996 년경)에 필요할 때입니다.
erickson

8
HashMap은 프로그래머가 threadSafe 코드를 실제로 사용할 때 작성할 수있는 유연성을 제공합니다. ConcurrentHashMap 또는 HashTable과 같은 스레드 안전 컬렉션이 필요한 경우는 거의 없었습니다. 내가 필요한 것은 스레드 안전하기 위해 동기화 된 블록의 특정 함수 세트 또는 특정 명령문입니다.
Gaurava Agarwal 2016

2
Hashtable은 더 이상 사용되지 않으며 스레드 안전이 아닌 환경에 HashMap을 사용하고 있습니다. 스레드 안전성이 필요한 경우 Collections.synchronizedMap ()을 사용하거나 해시 테이블보다 효율적인 ConcurrentHashMap을 사용할 수 있습니다.
Maneesh Kumar

1
더 이상 사용되지 않지만 더 이상 사용되지 않으며 이것이 왜 그런지 궁금합니다. 이 클래스 (및 같은 이유로 Vector)를 제거하면 기존 코드가 너무 많이 손상되고 @Deprecated로 주석을 달면 코드를 제거하려는 의도가 있음을 암시합니다.
Jilles van Gurp

682

많은 답변은 Hashtable이 동기화되었음을 나타냅니다. 실제로 이것은 당신을 거의 사지 않습니다. 접근자는 접근 자 / 뮤 테이터 메소드에서 동기화되어 맵에서 동시에 두 개의 스레드를 추가하거나 제거하지 않지만 실제 환경에서는 종종 추가 동기화가 필요합니다.

매우 일반적인 관용구는 "확인하고 입력"하는 것입니다. 즉 Map, 에서 항목을 찾아서 존재하지 않는 경우 추가합니다. 사용 여부 이것은 어떤 방법으로 원자 작동하지 않습니다 HashtableHashMap.

동등하게 동기화 HashMap할 수 있습니다 :

Collections.synchronizedMap(myMap);

그러나이 논리를 올바르게 구현 하려면 다음 양식을 추가로 동기화 해야 합니다.

synchronized(myMap) {
    if (!myMap.containsKey("tomato"))
        myMap.put("tomato", "red");
}

추가 Hashtable항목을 통해 항목을 수정 하지 않도록 보호하지 않는 한의 항목을 반복해도 (또는에 HashMap의해 획득 됨 Collections.synchronizedMap) 스레드로부터 안전하지 않습니다 Map.

ConcurrentMap인터페이스의 구현 (예 ConcurrentHashMap:)은 다음과 같은 스레드 안전 점검 후 동작 시맨틱 을 포함하여이 중 일부를 해결합니다 .

ConcurrentMap.putIfAbsent(key, value);

53
또한 HashMap이 수정되면이를 가리키는 반복자는 유효하지 않게됩니다.
Chris K

3
스레드 안전 측면에서 synchronized (myMap) {...}와 ConcurrentHashMap 사이에 차이점이 있습니까?
telebog

3
매우 사실, 나는 여기에 동일하게 설명하려고 노력했습니다 .. lovehasija.com/2012/08/16/…
Love Hasija

: @Bhushan : 그것은 최선 노력 원칙에 근거 해이 보장되지 동작을 발생합니다 docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
매트 스티븐슨

몇 년 동안 JVM 개발 승무원의 한복판에 있었기 때문에 Hashtable의 내부 동기화가 피해야 할 동시 코드를 작성할 때 고객 코드에서 손가락을 올바르게 가리키는 데 적어도 유용하다고 말할 수 있습니다. 우리는 원인이 동시에 수정되었을 때 HashMap 내부에서 실패에 대한 몇 가지 불만을 받았습니다 (따라서 "분명히 JDK / JVM 버그").
핫 릭

363

Hashtable레거시 코드로 간주됩니다. 에 대한 Hashtable사용 HashMap이나 파생을 수행 할 수없는 것은 HashMap없으므로 새로운 코드의 경우로 돌아가는 데 대한 정당성이 보이지 않습니다 Hashtable.


101
Hashtable javadoc (강조 추가)에서 : "Java 2 플랫폼 v1.2부터이 클래스는 Map 인터페이스를 구현하기 위해 개량되어 Java Collections Framework의 멤버가되었습니다 ." 그러나 레거시 코드라는 것이 맞습니다. Collections.synchronizedMap (HashMap)을 사용하면 동기화의 모든 이점을보다 효율적으로 얻을 수 있습니다. (Vector가 Collections.synchronizedList (ArrayList)의 레거시 버전 인 것과 유사 함)
Kip

15
@ aberrant80 : 불행히도 당신은 둘 사이에서 선택의 여지가 없으며 J2ME를 프로그래밍 할 때 Hashtable을 사용해야합니다 ...
pwes

6
이 답변은 삭제해야합니다. 잘못된 정보가 포함되어 있으며 많은 공감대가 있습니다.
anon58192932

@ anon58192932 질문을 수정하여 수정할 수 있습니까?
GC_

1
우리는 포스터 @ aberrant80 또는 관리자의 깃발을 주목하여 관심을 가져야합니다. 신고하면 도움이 될 수 있습니다. 지금 시도해보십시오.
anon58192932

189

이 질문은 종종 후보자가 수집 클래스의 올바른 사용법을 이해하고 사용 가능한 대체 솔루션을 알고 있는지 확인하기 위해 인터뷰에서 요청됩니다.

  1. HashMap클래스는 Hashtable동기화되지 않았으며 null을 허용한다는 점을 제외하고 대략와 같습니다. ( HashMapnull 값은 키와 값으로 Hashtable허용하고 nulls 는 허용하지 않습니다 ).
  2. HashMap 지도의 순서가 시간이 지남에 따라 일정하게 유지된다는 보장은 없습니다.
  3. HashMap동기화되지 않은 반면 Hashtable동기화됩니다.
  4. HashMap대한 열거자는 Hashtableis 안전 하지 않은 반면에 다른 열거자가 자체 메소드를 ConcurrentModificationException제외한 요소를 추가하거나 제거하여 구조적으로 맵을 수정하면 throw는 안전 하지 않습니다 . 그러나 이것은 보장 된 동작이 아니며 최선의 노력으로 JVM에 의해 수행됩니다.Iteratorremove()

몇 가지 중요한 용어에 대한 참고 사항 :

  1. 동기화는 한 시점에서 하나의 스레드 만 해시 테이블을 수정할 수 있음을 의미합니다. 기본적으로 이는 업데이트를 수행하기 전에 모든 스레드 Hashtable가 객체에 대한 잠금을 획득해야 하고 다른 스레드 는 잠금이 해제 될 때까지 대기해야 함을 의미합니다.
  2. 페일 세이프는 이터레이터와 관련이 있습니다. 컬렉션 객체에서 반복자가 생성되고 다른 스레드가 컬렉션 객체를 "구조적으로"수정하려고하면 동시 수정 예외가 발생합니다. set컬렉션을 "구조적으로"수정하지 않기 때문에 다른 스레드가 메소드 를 호출 할 수도 있습니다. 그러나을 호출하기 전에 set컬렉션이 구조적으로 수정 된 IllegalArgumentException경우 던져집니다.
  3. 구조적으로 수정하는 것은 맵의 구조를 효과적으로 변경할 수있는 요소를 삭제하거나 삽입하는 것을 의미합니다.

HashMap 에 의해 동기화 될 수있다

Map m = Collections.synchronizeMap(hashMap);

지도는 열거 객체를 통한 반복을 직접 지원하는 대신 컬렉션보기를 제공합니다. 컬렉션 뷰는이 섹션의 뒷부분에서 설명하는 것처럼 인터페이스의 표현성을 크게 향상시킵니다. 맵을 사용하면 키, 값 또는 키-값 쌍을 반복 할 수 있습니다. Hashtable세 번째 옵션은 제공하지 않습니다. 맵은 반복 중에 항목을 안전하게 제거 할 수있는 방법을 제공합니다. Hashtable하지 않았다. 마지막으로, Map은 Hashtable인터페이스 의 약간의 결함을 수정합니다 . Hashtablecontains라는 메소드가 있는데 Hashtable, 주어진 값 이 포함되어 있으면 true를 리턴합니다 . 이름이 주어지면 Hashtable키가 a의 기본 액세스 메커니즘이기 때문에 주어진 키 가 포함되어 있으면이 메소드가 true를 반환 할 것으로 예상 Hashtable됩니다. 지도 인터페이스는 메소드의 이름을 바꾸어 이러한 혼란의 원인을 제거합니다. containsValue. 또한 인터페이스의 일관성 ( containsValue병렬)을 향상시킵니다 containsKey.

지도 인터페이스


19
이 답변에는 적어도 2 개의 중대한 사실 부정확성이 포함되어 있습니다. 확실히이 많은 공감대를받을 자격이 없습니다.
Stephen C

58
1) HashMap의 반복자는 오류 방지 기능이 아닙니다. 그들은 빠르다. 이 두 용어 사이에는 의미에 큰 차이가 있습니다. 2)에 set작업 이 없습니다 HashMap. 3) 이전 변경 사항이 있으면 put(...)작업 이 중단되지 않습니다 IllegalArgumentException. 4) 매핑을 변경하면 페일 패스트 동작 HashMap 발생합니다. 5) 빠른 동작 보장됩니다. ( HashTable동시에 수정 하는 경우 a의 동작은 보장되지 않습니다 . 실제 동작은 ... 예측할 수 없습니다.)
Stephen C

25
6) Hashtable지도 요소의 순서가 시간이 지남에 따라 안정적임을 보장하지 않습니다. (당신은 아마 혼란 스럽 Hashtable습니다 LinkedHashMap.)
Stephen C

4
다른 사람들은 요즘 학생들이 컬렉션의 "동기화 버전"을 얻는 것이 어쨌든 복합 작업을 외부에서 동기화 할 필요가 없다는 잘못된 아이디어를 얻고 있다고 걱정하고 있습니까? 내가 좋아하는 예는 thing.set(thing.get() + 1);특히 get()and 및 set()동기화 된 메소드 인 경우 완전히 보호되지 않은 것으로 놀라움으로 초보자를 잡는 경우가 많습니다 . 그들 중 많은 사람들이 마술을 기대하고 있습니다.

HashMap의 반복기는 안전하지 않습니다
Abdul

130

HashMap: Map해시 코드를 사용하여 배열을 색인화하는 인터페이스 의 구현입니다 . Hashtable: 1998 년 안녕하세요. 그들은 컬렉션 API를 다시 원합니다.

진지하게, 당신은 Hashtable완전히 떨어져있는 것이 좋습니다 . 단일 스레드 앱의 경우 동기화 오버 헤드가 추가로 필요하지 않습니다. 동시성이 높은 앱의 경우 편집증 동기화로 인해 기아, 교착 상태 또는 불필요한 가비지 수집 일시 중지가 발생할 수 있습니다. Tim Howland가 지적한 것처럼 ConcurrentHashMap대신 사용할 수 있습니다 .


이것은 실제로 의미가 있습니다. ConcurrentHashMaps는 동기화의 자유를 제공하고 디버깅이 훨씬 더 쉽습니다.
prap19

1
이것은 Java 또는 모든 해시 맵 구현에만 해당됩니다.

125

명심 HashTable자바 컬렉션 프레임 워크 (JCF)를 도입하고 나중에 구현하기 위해서 개량되기 전에 기존 클래스했다 Map인터페이스를. 그래서이었다 VectorStack.

따라서 다른 사람들이 지적했듯이 JCF에는 항상 더 나은 대안이 있기 때문에 항상 새 코드에서 멀리하십시오 .

다음은 유용한 Java 콜렉션 치트 시트 입니다. 회색 블록에는 레거시 클래스 HashTable, Vector 및 Stack이 포함되어 있습니다.

여기에 이미지 설명을 입력하십시오


72

이미 게시 된 좋은 답변이 많이 있습니다. 몇 가지 새로운 포인트를 추가하고 요약합니다.

HashMapHashtable모두를 저장하는 데 사용되는 키 값 데이터 형태 . 둘 다 고유 키를 저장하기 위해 해싱 기술을 사용하고 있습니다. 그러나 아래에 주어진 HashMap과 Hashtable 클래스에는 많은 차이점이 있습니다.

해시 맵

  1. HashMap동기화되지 않았습니다. 스레드 안전하지 않으며 적절한 동기화 코드가 없으면 많은 스레드간에 공유 할 수 없습니다.
  2. HashMap 하나의 null 키와 여러 null 값을 허용합니다.
  3. HashMap JDK 1.2에 도입 된 새로운 클래스입니다.
  4. HashMap 빠릅니다.
  5. HashMap이 코드를 호출 하여 로 동기화 할 수 있습니다
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap Iterator에 의해 순회됩니다.
  7. 반복자 HashMap가 실패했습니다.
  8. HashMap AbstractMap 클래스를 상속합니다.

해시 테이블

  1. Hashtable동기화됩니다. 스레드 안전하고 많은 스레드와 공유 할 수 있습니다.
  2. Hashtable null 키 또는 값을 허용하지 않습니다.
  3. Hashtable 레거시 클래스입니다.
  4. Hashtable 느리다.
  5. Hashtable 내부적으로 동기화되며 동기화 할 수 없습니다.
  6. Hashtable Enumerator와 Iterator에 의해 순회됩니다.
  7. 열거자가 Hashtable실패하지 않습니다.
  8. Hashtable Dictionary 클래스를 상속합니다.

더 읽기 Java에서 HashMap과 Hashtable의 차이점은 무엇입니까?

여기에 이미지 설명을 입력하십시오


- 꽤 많은이 답변에 (의 dupicate) 적용 stackoverflow.com/a/39785829/432903을 .
prayagupd

왜 ~ " 해시 테이블은 레거시 클래스입니다 "라고 말합니까? 이에 대한 지원 문서는 어디에 있습니까?
IgorGanapolsky

2
- 당신이 읽을 수 있습니다 @IgorGanapolsky stackoverflow.com/questions/21086307/...
roottraveller

HashMap 유지 관리는 TreeMap보다 비용이 많이 듭니다. HashMap이 불필요한 추가 버킷을 생성하기 때문입니다.
Abdul

64

izb가 말한 것 외에도 HashMapnull 값을 허용하지만 Hashtable그렇지는 않습니다.

또한 Javadocs 상태 로서 더 이상 사용되지 않으며 인터페이스 로 대체 된 클래스 를 Hashtable확장합니다 .DictionaryMap


3
그러나 그것이 HashTable을 쓸모 없게 만들지 않습니까?
Pacerier

@Pacerier HashTable은 Java 1.7부터 더 이상 사용되지 않습니다.
Majid Ali Khan

62

이 차트를 살펴보십시오. 그것은과 함께 다른 데이터 구조 사이의 비교를 제공 HashMap하고 Hashtable. 비교는 정확하고 명확하며 이해하기 쉽습니다.

자바 컬렉션 매트릭스


49

Hashtable와 비슷 HashMap하고 비슷한 인터페이스를 가지고 있습니다. 메소드가 동기화 HashMap되므로 레거시 애플리케이션에 대한 지원이 필요하거나 동기화가 필요한 경우가 아니면 을 사용하는 것이 좋습니다 Hashtables. 따라서 멀티 스레딩이 아닌 경우 HashMaps최선의 방법입니다.


36

해시 테이블과 해시 맵의 또 다른 주요 차이점은 HashMap의 Iterator가 빠른 속도이고 Hashtable의 열거자는 그렇지 않고 다른 Thread가 Iterator의 자체 remove () 메소드를 제외한 요소를 추가하거나 제거하여 구조적으로 맵을 수정하는 경우 ConcurrentModificationException을 발생시키는 것입니다. 그러나 이것은 보장 된 동작이 아니며 최선의 노력으로 JVM에 의해 수행 될 것입니다. "

내 출처 : http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html


36

여기에 이미 언급 된 다른 모든 중요한 측면 외에도 Collections API (예 : Map 인터페이스)는 Java 스펙에 대한 "최신 및 가장 큰"추가 사항을 준수하도록 항상 수정되고 있습니다.

예를 들어, Java 5 Map 반복을 비교하십시오.

for (Elem elem : map.keys()) {
  elem.doSth();
}

이전 해시 테이블 접근 방식과 비교 :

for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
  Elem elem = (Elem) en.nextElement();
  elem.doSth();
}

Java 1.8에서 우리는 또한 좋은 오래된 스크립팅 언어와 같이 HashMaps를 구성하고 액세스 할 수 있다고 약속했습니다.

Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];

업데이트 : 아니요, 1.8에 착륙하지 않습니다 ... :(

Project Coin의 수집 기능 향상이 JDK8에 있습니까?


34

Hashtable동기화 HashMap되지 않지만 동기화 되지는 않습니다. 그 수 Hashtable보다 느립니다 Hashmap.

스레드되지 않은 앱 HashMap의 경우 기능 측면에서 동일하므로 사용 하십시오.


30
  • HashTable 은 동기화되며 단일 스레드에서 사용 하는 경우 동기화되지 않은 버전 인 HashMap 을 사용할 수 있습니다 . 동기화되지 않은 객체는 종종 약간 더 성능이 좋습니다. 그런데 여러 스레드가 동시에 HashMap에 액세스하고 스레드 중 하나 이상이 맵을 구조적으로 수정하는 경우 외부 적으로 동기화해야합니다. 다음을 사용하여 동기화되지 않은 맵을 동기화 된 맵으로 랩핑 할 수 있습니다.

    Map m = Collections.synchronizedMap(new HashMap(...));
  • HashTable은 널이 아닌 오브젝트 만 키 또는 값으로 포함 할 수 있습니다. HashMap은 하나의 널 키와 널 값을 포함 할 수 있습니다.

  • 반복자가 자체 remove 메소드를 제외하고 어떤 방식 으로든 반복자가 작성된 후 언제라도 맵이 구조적으로 수정되면 Map이 리턴 한 반복자는 실패가 빠릅니다 ConcurrentModificationException. 따라서 동시 수정에 직면하여 반복자는 미래에 결정되지 않은 시간에 임의의 비 결정적 동작을 위험에 빠뜨리기보다는 신속하고 깨끗하게 실패합니다. 반면에 열거 유형이 해시 테이블의 키와 요소 메소드에 의해 반환되는 르파 없습니다.

  • HashTable 및 HashMap은 Java Collections Framework의 멤버입니다 (Java 2 플랫폼 v1.2 이후 HashTable은 맵 인터페이스를 구현하기 위해 개량되었습니다).

  • HashTable은 레거시 코드로 간주되며 스레드 안전성이 높은 동시 구현이 필요한 경우 Hashtable 대신 ConcurrentHashMap 을 사용 하는 것이 좋습니다.

  • HashMap은 요소가 반환되는 순서를 보장하지 않습니다. HashTable의 경우에는 같지만 완전히 확실하지는 않지만 명확하게 설명하는 리소스를 찾지 못했습니다.


30

HashMapHashtable뿐만 아니라 중요한 알고리즘 차이가 있습니다. 아무도 이것을 전에 언급하지 않았으므로 내가 그것을 제기하는 이유입니다. HashMap두 가지 크기의 힘으로 해시 테이블을 생성하고 모든 버킷에 최대 약 8 개의 요소 (충돌)를 갖도록 동적으로 늘리고 일반적인 요소 유형에 대해 요소를 잘 저어줍니다. 그러나 Hashtable구현을 통해 해킹을 더 잘 제어 할 수 있습니다. 예를 들어 값 도메인 크기에 가장 가까운 소수를 사용하여 테이블 크기를 수정할 수 있습니다. 그러면 HashMap보다 성능이 향상됩니다. 어떤 경우에는.

이 질문에서 광범위하게 논의 된 명백한 차이점과는 별도로, 해시 테이블을 해시를보다 잘 제어 할 수있는 "수동 드라이브"자동차로, HashMap을 일반적으로 잘 수행하는 "자동 드라이브"로 간주합니다.


27

here 정보를 기반으로 HashMap을 사용하는 것이 좋습니다. 가장 큰 장점은 반복기를 통해 수행하지 않는 한 Java가 반복하는 동안 Java가 수정하지 못하게한다는 것입니다.


5
실제로 그것을 막는 것이 아니라 그것을 감지하고 오류를 던집니다.
Bart van Heukelom

1
기본 컬렉션이 수정되기 전에 ConncurrentModificationException이 발생하지만 잘못 될 수 있다고 확신합니다.
11

그것은 것입니다 시도하는 동시 변경을 감지하고 예외를 던져. 그러나 스레드로 무언가를하고 있다면 약속 할 수 없습니다. 물론 파손을 포함하여 모든 것이 발생할 수 있습니다 .
cHao

24

Collection컨테이너라고도하는 A 는 단순히 여러 요소를 단일 단위로 그룹화하는 객체입니다. Collection집계 데이터를 저장, 검색, 조작 및 통신하는 데 사용됩니다. 컬렉션 프레임 워크 W 는 컬렉션 을 나타내고 조작하기위한 통합 아키텍처입니다.

HashMap JDK1.2및 해시 테이블 JDK1.0, 양쪽에서 표시되는 오브젝트 그룹 나타내는 데 사용되는 <Key, Value>한 쌍. 각 <Key, Value>쌍을 Entry객체 라고 합니다. 항목 모음은 HashMap및 의 객체에 의해 참조됩니다 Hashtable. 컬렉션의 키는 고유하거나 고유해야합니다. [매핑 된 값을 특정 키로 검색하는 데 사용됩니다. 컬렉션의 값을 복제 할 수 있습니다.]


« 수퍼 클래스, 레거시 및 컬렉션 프레임 워크 멤버

Hashtable은에서 도입 된 레거시 클래스 JDK1.0이며 Dictionary 클래스의 하위 클래스입니다. From JDK1.2Hashtable은 컬렉션 프레임 워크의 멤버를 만들기 위해 Map 인터페이스 를 구현하도록 다시 엔지니어링되었습니다 . HashMap은에서 소개를 시작할 때부터 Java Collection Framework의 멤버입니다 JDK1.2. HashMap은 AbstractMap 클래스의 서브 클래스입니다.

public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }

public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }

« 초기 용량 및 부하 계수

용량은 해시 테이블의 버킷 수이며 초기 용량은 단순히 해시 테이블이 생성 될 때의 용량입니다. 해시 테이블은 열려 있습니다. " hashcollision" 의 경우 단일 버킷은 여러 항목을 저장하며이 항목은 순차적으로 검색해야합니다. 로드 팩터는 용량이 자동으로 증가하기 전에 해시 테이블이 얼마나 가득 찼는 지 측정합니다.

HashMap은 기본 초기 용량 (16) 과 기본로드 팩터 (0.75) 로 빈 해시 테이블을 구성합니다 . Hashtable은 기본 초기 용량 (11) 과로드 팩터 / 채우기 비율 (0.75)로 빈 해시 테이블을 구성 합니다.

해시 맵 및 해시 테이블

« 해시 충돌의 경우 구조 수정

HashMap, Hashtable해시 충돌의 경우에 그들은 연결리스트에서 맵 항목을 저장합니다. Java8에서HashMap 해시 버킷이 특정 임계 값을 초과하는 경우 해당 버킷은에서 전환됩니다 linked list of entries to a balanced tree. 최악의 성능을 O (n)에서 O (log n)로 향상시킵니다. 목록을 이진 트리로 변환하는 동안 해시 코드는 분기 변수로 사용됩니다. 동일한 버킷에 두 개의 다른 해시 코드가있는 경우 하나는 더 큰 것으로 간주되어 트리의 오른쪽으로 가고 다른 하나는 왼쪽으로갑니다. 그러나 두 해시 코드가 같으면 HashMap키를 비교할 수 있다고 가정하고 키를 비교하여 방향을 결정하여 일부 순서를 유지할 수 있습니다. 키를 HashMap 비슷한 것으로 만드는 것이 좋습니다 . 버킷 크기에 도달하면 항목 추가시TREEIFY_THRESHOLD = 8링크 된 항목 목록을 균형 잡힌 트리로 변환, 이하의 항목을 제거하면 TREEIFY_THRESHOLD 대부분 UNTREEIFY_THRESHOLD = 6균형 트리를 연결된 항목 목록으로 다시 변환합니다. Java 8 SRC , 스택 포스트

« 콜렉션-뷰 반복, 페일-페스트 및 페일-세이프

    +--------------------+-----------+-------------+
    |                    | Iterator  | Enumeration |
    +--------------------+-----------+-------------+
    | Hashtable          | fail-fast |    safe     |
    +--------------------+-----------+-------------+
    | HashMap            | fail-fast | fail-fast   |
    +--------------------+-----------+-------------+
    | ConcurrentHashMap  |   safe    |   safe      |
    +--------------------+-----------+-------------+

Iterator본질적으로 실패입니다. 즉, 자체 remove () 메소드 이외의 반복을 수행하는 동안 컬렉션을 수정하면 ConcurrentModificationException이 발생합니다. 어디로하는 Enumeration페일 세이프 (fail-safe) 자연입니다. 반복하는 동안 컬렉션이 수정되면 예외가 발생하지 않습니다.

Java API Docs에 따르면 반복자보다 항상 반복자가 선호됩니다.

참고 : 열거 인터페이스의 기능은 Iterator 인터페이스에 의해 복제됩니다. 또한 Iterator는 선택적 제거 작업을 추가하고 메소드 이름이 더 짧습니다. 새로운 구현에서는 열거 자보다 반복자를 사용하는 것이 좋습니다.

에서 자바 5 인 ConcurrentMap 인터페이스를 도입 : ConcurrentHashMap- 매우 동시, 고성능 ConcurrentMap해시 테이블 바탕으로 구현. 이 구현은 검색을 수행 할 때 차단하지 않으며 클라이언트가 업데이트의 동시성 수준을 선택할 수 있도록합니다. 그것은 드롭 인 교체를위한 것입니다 Hashtable구현하는 것 외에 : ConcurrentMap, 그것은에 "레거시"방법의 독특한 모두를 지원합니다 Hashtable.

  • HashMapEntrys 값은 휘발성 이므로 경합 수정 및 후속 판독에 대한 미세한 입자 일관성을 보장합니다. 각 읽기는 가장 최근에 완료된 업데이트를 반영합니다

  • 이터레이터와 열거는 페일 세이프입니다. 이터레이터 / 열거를 생성 한 이후 어느 시점에서 상태를 반영합니다. 따라서 일관성이 떨어지지 만 동시에 읽고 수정할 수 있습니다. ConcurrentModificationException을 발생시키지 않습니다. 그러나 반복기는 한 번에 하나의 스레드 만 사용하도록 설계되었습니다.

  • 마찬가지로 Hashtable하지만 달리 HashMap,이 클래스가 null이 키 또는 값으로 사용할 수 없습니다.

public static void main(String[] args) {

    //HashMap<String, Integer> hash = new HashMap<String, Integer>();
    Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
    //ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();

    new Thread() {
        @Override public void run() {
            try {
                for (int i = 10; i < 20; i++) {
                    sleepThread(1);
                    System.out.println("T1 :- Key"+i);
                    hash.put("Key"+i, i);
                }
                System.out.println( System.identityHashCode( hash ) );
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }
    }.start();
    new Thread() {
        @Override public void run() {
            try {
                sleepThread(5);
                // ConcurrentHashMap  traverse using Iterator, Enumeration is Fail-Safe.

                // Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
                for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
                    sleepThread(1);
                    System.out.println("T2 : "+ e.nextElement());
                }

                // HashMap traverse using Iterator, Enumeration is Fail-Fast.
                /*
                for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
                    sleepThread(1);
                    System.out.println("T2 : "+ it.next());
                    // ConcurrentModificationException at java.util.Hashtable$Enumerator.next
                }
                */

                /*
                Set< Entry<String, Integer> > entrySet = hash.entrySet();
                Iterator< Entry<String, Integer> > it = entrySet.iterator();
                Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
                while( entryEnumeration.hasMoreElements() ) {
                    sleepThread(1);
                    Entry<String, Integer> nextElement = entryEnumeration.nextElement();
                    System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
                    //java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
                    //                                          at java.util.HashMap$EntryIterator.next
                    //                                          at java.util.Collections$3.nextElement
                }
                */
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }
    }.start();

    Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
    try {
        unmodifiableMap.put("key4", "unmodifiableMap");
    } catch (java.lang.UnsupportedOperationException e) {
        System.err.println("UnsupportedOperationException : "+ e.getMessage() );
    }
}
static void sleepThread( int sec ) {
    try {
        Thread.sleep( 1000 * sec );
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

« 널 키와 널 값

HashMap최대 하나의 널 키와 임의의 수의 널 값을 허용합니다. 어디로 Hashtable키 또는 값 널 (null)이이 NullPointerException이 발생 다음의 경우에도 하나의 널 (null) 키와 null 값을 허용하지 않습니다.

« 동기화 된 스레드 안전

Hashtable내부적으로 동기화됩니다. 따라서 Hashtable멀티 스레드 응용 프로그램에서 사용하는 것이 매우 안전 합니다. HashMap내부적으로 동기화되지 않은 곳 . 따라서 HashMap외부 동기화없이 다중 스레드 응용 프로그램에서 사용하는 것은 안전하지 않습니다 . 방법을 HashMap사용하여 외부에서 동기화 할 수 있습니다 Collections.synchronizedMap().

« 성능

으로 Hashtable내부적으로 동기화되어,이 만드는 Hashtable약간 느린 것보다 HashMap.


@보다


18

스레드 응용 프로그램의 경우 성능 요구 사항에 따라 ConcurrentHashMap을 사용하여 벗어날 수 있습니다.


17

1. HashmapHashTable모두 저장 키와 값.

2.로 Hashmap하나의 키를 저장할 수 있습니다 null. Hashtable저장할 수 없습니다 null.

3. HashMap동기화되지 않았지만 Hashtable동기화되었습니다.

4. HashMap동기화 할 수 있습니다Collection.SyncronizedMap(map)

Map hashmap = new HashMap();

Map map = Collections.SyncronizedMap(hashmap);

16

외에도 이미 언급의 차이에서, 자바 (8) 이후, 주목해야한다 HashMap동적으로 높은 해시 충돌, 최악의 경우 존재하는 경우에도 그래서,의 TreeNode (레드 - 블랙 트리)와 각 버킷에 사용되는 노드 (연결리스트)를 대체 할 때를 검색

O 대 (로그 (N)) HashMap 에서 O (N) Hashtable.

* 상기의 개선이인가되지 않은 Hashtable또, 만에 HashMap, LinkedHashMap그리고 ConcurrentHashMap.

참고로 현재

  • TREEIFY_THRESHOLD = 8 : 버킷에 8 개 이상의 노드가 포함 된 경우 연결된 목록이 균형 트리로 변환됩니다.
  • UNTREEIFY_THRESHOLD = 6 : 버킷이 너무 작아지면 (제거 또는 크기 조정으로 인해) 트리가 다시 연결된 목록으로 변환됩니다.

14

HashTable과 HashMaps에는 5 가지 기본 차이점이 있습니다.

  1. 맵을 사용하면 키, 값 및 두 키-값 쌍을 반복하고 검색 할 수 있습니다. 여기서 HashTable에이 기능이 모두 없습니다.
  2. Hashtable에는 contains () 함수가 있는데, 사용하기가 매우 혼란 스럽다. 포함의 의미가 약간 어긋나 기 때문입니다. 키 또는 값을 포함하는지 여부 이해하기 어렵다. Maps에서 우리는 ContainsKey () 및 ContainsValue () 함수를 가지고 있으며 이해하기 매우 쉽습니다.
  3. 해시 맵에서는 안전하게 반복하면서 요소를 제거 할 수 있습니다. 해시 테이블에서는 불가능합니다.
  4. 해시 테이블은 기본적으로 동기화되므로 여러 스레드에서 쉽게 사용할 수 있습니다. HashMaps는 기본적으로 동기화되지 않으므로 단일 스레드로만 사용할 수 있습니다. 그러나 Collections util 클래스의 synchronizedMap (Map m) 함수를 사용하여 여전히 HashMap을 동기화 된 것으로 변환 할 수 있습니다.
  5. HashTable은 null 키 또는 null 값을 허용하지 않습니다. HashMap은 하나의 null 키와 여러 null 값을 허용합니다.

13

나의 작은 기여 :

  1. 우선 대부분의 사이에 서로 다른 의미 HashtableHashMap그 인은 HashMap되지 스레드 안전 동안은 Hashtable스레드 안전 모음입니다.

  2. 사이 두 번째로 중요한 차이점 Hashtable하고 HashMap있기 때문에, 성능입니다 HashMap그것은 더 이상 수행 할 동기화되지 않습니다 Hashtable.

  3. 에 세 번째 차이 HashtableHashMap즉이 Hashtable되지 않는 클래스입니다 그리고 당신은 사용해야 ConcurrentHashMap대신에 Hashtable자바있다.


11

HashMap : java.util 패키지에서 사용할 수있는 클래스이며 키 및 값 형식으로 요소를 저장하는 데 사용됩니다.

Hashtable : 컬렉션 프레임 워크 내에서 인식되는 레거시 클래스입니다.


그렇다면 답변이 아닌 주석에 있어야합니다.
manikant gautam

10

HashTable 은 더 이상 사용해서는 안되는 jdk의 레거시 클래스입니다. 사용법을 ConcurrentHashMap 으로 바꾸십시오 . 당신은 스레드 안전, 사용이 필요하지 않은 경우 의 HashMap 하지 스레드 하지만, 빠르고 사용 메모리를 적게.


그 당시 다른 답변은 HashTable을 닫지 않았지만 스레드 안전하다고 설명했기 때문에. 진실은 코드에서 HashTable을 보자 마자 비트를 건너 뛰지 않고 ConcurrentHashMap으로 바꾸어야한다는 것입니다. 스레드 안전성이 중요하지 않은 경우 HashMap을 사용하여 성능을 약간 향상시킬 수 있습니다.
jontejj

10
  1. Hashtable동기화 HashMap되지 않은 반면 동기화 됩니다.
  2. 또 다른 차이점은 HashMap의 열거자는 실패 안전하지만 열거 Hashtable자는 그렇지 않습니다. 반복하는 동안지도를 변경하면 알 수 있습니다.
  3. HashMapnull 값을 허용하지만 허용 Hashtable하지 않습니다.

3
HashMap 이터레이터는 페일 세이프가 아닌 페일 패스트입니다. 따라서 반복하는 동안 수정할 수있는 ConcurrentHashMap이 있습니다. 이 게시물을 확인하십시오 journaldev.com/122/…
Pankaj

9

해시 맵 및 해시 테이블

  • HashMap 및 HashTable에 대한 몇 가지 중요한 사항. 자세한 내용은 아래를 참조하십시오.

1) Hashtable과 Hashmap은 java.util.Map 인터페이스를 구현합니다. 2) Hashmap과 Hashtable은 모두 해시 기반 컬렉션입니다. 해싱 작업. HashMap과 HashTable의 유사점입니다.

  • HashMap과 HashTable의 차이점은 무엇입니까?

1) 첫 번째 차이점은 HashMap은 스레드로부터 안전하지 않은 반면 HashTable은 ThreadSafe이지만
2) HashMap은 스레드로부터 안전하지 않기 때문에 성능이 더 좋습니다. 스레드 안전하기 때문에 해시 테이블 성능이 현명하지 않습니다. 여러 스레드가 동시에 Hashtable에 액세스 할 수 없습니다.


2
이 답변은 일부 측면에서 정확하지 않기 때문에 투표에 실패했습니다. Hashtable은 Map 인터페이스를 구현하지 않지만 Dictionary 클래스 만 확장합니다.이 클래스는 더 이상 사용되지 않습니다.
Yannis Sermetziadis

8

Hashtable:

해시 테이블 은 키-값 쌍의 값을 유지하는 데이터 구조입니다. 키와 값 모두에 대해 널을 허용하지 않습니다. 당신은 얻을 것이다 NullPointerException당신은 null 값을 추가합니다. 동기화되었습니다. 따라서 비용이 발생합니다. 특정 시간에 하나의 스레드 만 HashTable 에 액세스 할 수 있습니다 .

:

import java.util.Map;
import java.util.Hashtable;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states= new Hashtable<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    //will throw NullPointerEcxeption at runtime

    System.out.println(states.get(1));
    System.out.println(states.get(2));
//  System.out.println(states.get(3));

    }
}

해시지도 :

HashMapHashtable 과 비슷 하지만 키 값 쌍도 허용합니다. 키와 값 모두에 대해 널을 허용합니다. 그 성능은 더 나은보다 HashTable가 있기 때문에, unsynchronized.

예:

import java.util.HashMap;
import java.util.Map;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states = new HashMap<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    // Okay
    states.put(null,"UK");

    System.out.println(states.get(1));
    System.out.println(states.get(2));
    System.out.println(states.get(3));

    }
}

5

HashMap에뮬레이션되어 사용할 수있는 GWT client code반면 Hashtable그렇지 않습니다.


두 API의 차이점에 대한 포괄적 인 설명입니까?
IgorGanapolsky

예 (sic!). 그것이 모든 GWT 개발자가 알아야 할 것입니다.
pong

5

이전 주제와 고전적인 주제에 대해서는 다음을 설명하는 유용한 블로그를 추가하십시오.

http://blog.manishchhabra.com/2012/08/the-5-main-differences-betwen-hashmap-and-hashtable/

Manish Chhabra의 블로그

HashMap과 Hashtable 간의 5 가지 주요 차이점

HashMap과 Hashtable은 모두 java.util.Map 인터페이스를 구현하지만보다 효율적인 코드를 작성하려면 Java 개발자가 이해해야 할 몇 가지 차이점이 있습니다. Java 2 플랫폼 v1.2부터 Hashtable 클래스는 Map 인터페이스를 구현하도록 개조되어 Java Collections Framework의 멤버가되었습니다.

  1. HashMap과 Hashtable의 주요 차이점 중 하나는 HashMap이 동기화되지 않고 Hashtable이 동기화된다는 것입니다. 즉, Hashtable은 스레드로부터 안전하고 여러 스레드간에 공유 될 수 있지만 HashMap은 적절한 동기화없이 여러 스레드간에 공유 될 수 없습니다. Java 5는 Hashtable의 대안이며 Java의 Hashtable보다 더 나은 확장 성을 제공하는 ConcurrentHashMap을 도입했습니다. 기본적으로 해시 테이블에서 업데이트를 수행하기 전에 모든 스레드가 객체에 대한 잠금을 획득해야하고 다른 스레드는 잠금이 해제 될 때까지 대기해야 함을 의미합니다.

  2. HashMap 클래스는 null을 허용한다는 점을 제외하고 Hashtable과 거의 동일합니다. HashMap은 null 값을 키와 값으로 허용하고 Hashtable은 null을 허용하지 않습니다.

  3. HashMap과 Hashtable의 세 번째 중요한 차이점은 HashMap의 Iterator는 페일 패스트 반복자이며 Hashtable의 열거자는 그렇지 않으며 다른 Thread가 Iterator의 자체 제거를 제외한 요소를 추가하거나 제거하여 구조적으로 맵을 수정하면 ConcurrentModificationException을 발생시킵니다 ) 방법. 그러나 이것은 보장 된 동작이 아니며 최선의 노력으로 JVM이 수행합니다. 이것은 또한 Java에서 열거와 반복자의 중요한 차이점입니다.

  4. Hashtable과 HashMap의 또 다른 두드러진 차이점은 스레드 안전성과 동기화로 인해 단일 스레드 환경에서 사용되는 경우 Hashtable이 HashMap보다 훨씬 느리다는 것입니다. 따라서 동기화가 필요하지 않고 HashMap이 하나의 스레드에서만 사용되는 경우 Java에서 Hashtable을 수행합니다.

  5. HashMap은 맵 순서가 시간이 지남에 따라 일정하게 유지된다고 보장하지 않습니다.

HashMap은 다음을 통해 동기화 될 수 있습니다.

Map m = Collections.synchronizedMap(hashMap);

요약하면 Java의 Hashtable과 HashMap 사이에는 스레드 안전성과 속도가 크게 다르며, 스레드 안전성이 절대적으로 필요한 경우 Hashtable 만 사용한다는 점에 따라 Java 5를 실행중인 경우 Java에서 ConcurrentHashMap을 사용하는 것이 좋습니다.


ConcurrentHashMap은 읽기 동기화되지 않지만 Hashtable은 동기화됩니다. 따라서 쓰기와 동시에 많은 양의 읽기 작업이 수행되는 경우 데이터 무결성에 관심이 있으면 Hashtable이 더 나은 서비스를 제공합니다.
IgorGanapolsky 2014 년

5

HashMapHashtable은 모두 키 및 값 형식으로 데이터를 저장하는 데 사용됩니다. 둘 다 고유 키를 저장하기 위해 해싱 기술을 사용하고 있습니다. 그러나 아래에 주어진 HashMap 클래스와 Hashtable 클래스에는 많은 차이점이 있습니다.

여기에 이미지 설명을 입력하십시오


멋진 시각적 요약!
Nadjib Mami
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.