HashMapとHashtableの違い

1. 概要

この短いチュートリアルでは、_https://www.baeldung.com/java-hash-table [Hashtable] _と_https://www.baeldung.com/java-hashmapのコアの違いに焦点を当てます。 [ハッシュマップ] _。

*2. Java *の_Hashtable_および_HashMap_

_Hashtable_と_HashMap_は非常によく似ています。どちらも_Map_インターフェイスを実装するコレクションです。
また、_put()_、_ get()_、_ remove()_、および_containsKey()_メソッドは、一定時間のパフォーマンスO(1)を提供します。 内部的に、これらのメソッドは、データを保存するためのバケットを使用したハッシュの一般的な概念に基づいて機能します。
どちらのクラスも要素の挿入順序を維持しません。 つまり、追加された最初のアイテムは、値を反復処理するときに最初のアイテムではない場合があります。
しかし、それらにはいくつかの違いがあり、状況によっては他のものよりも優れています。 これらの違いを詳しく見てみましょう。

*3. Hashtable_と_HashMap *の違い

* 3.1。 同期*

まず、* _ Hashtable_はスレッドセーフ*であり、アプリケーション内の複数のスレッド間で共有できます。
一方、_HashMap_は同期されておらず、追加の同期コードなしでは複数のスレッドからアクセスできません。 Collection_Collections.synchronizedMap()_を使用して、スレッドセーフバージョンの_HashMap_を作成できます。 _synchronized_キーワードを使用して、カスタムロックコードを作成するか、コードをスレッドセーフにすることもできます。
_HashMap_は同期されないため、_Hashtable_よりも高速で、使用するメモリも少なくなります。 一般に、単一のスレッドアプリケーションでは、非同期オブジェクトは同期オブジェクトよりも高速です。

* 3.2。 ヌル値*

もう1つの違いは、__ nullhand__handlingです。 _HashMap_は、_null_をキーとして1つ_Entry_を追加し、_null_を値として多くのエントリを追加できます。 対照的に、* _Hashtable_は_null_をまったく許可しません*。 _null_と_HashMap_の例を見てみましょう:
HashMap<String, String> map = new HashMap<String, String>();
map.put(null, "value");
map.put("key1", null);
map.put("key2", null);
これは次のようになります。
assertEquals(3, map.size());
次に、Hashtableの違いを見てみましょう。
Hashtable<String, String> table = new Hashtable<String, String>();
table.put("key", null);
これにより、_NullPointerException_が発生します。 _null_をキーとしてオブジェクトを追加すると、_NullPointerException_も発生します。
table.put(null, "value");

* 3.3。 要素の繰り返し*

_HashMap_はlink:/java-iterator[_Iterator_]を使用して値を反復処理しますが、_Hashtable_には_Enumerator_があります。 _Iterator_は_Enumerator_の後継であり、いくつかの欠点を取り除きます。 たとえば、_Iterator_には、基になるコレクションから要素を削除する_remove()_メソッドがあります。
_Iterator_はlink:/java-fail-safe-vs-fail-fast-iterator[fail-fast iterator]です。 つまり、基礎となるコレクションが反復中に変更されると、link:/java-concurrentmodificationexception[_ConcurrentModificationException_]がスローされます。 フェイルファストの例を見てみましょう。
HashMap<String, String> map = new HashMap<String, String>();
map.put("key1", "value1");
map.put("key2", "value2");

Iterator<String> iterator = map.keySet().iterator();
while(iterator.hasNext()){
    iterator.next();
    map.put("key4", "value4");
}
コレクションを反復処理している間に_put()_を呼び出しているため、これは_ConcurrentModificationException_例外をスローします。

*4. HashMap Hashtable *を選択する場合

非同期またはシングルスレッドのアプリケーションには、_HashMap_を使用する必要があります。
JDK 1.8以降、_Hashtable_は非推奨になったことに言及する価値があります。 ただし、https://www.baeldung.com/java-concurrent-map [_ConcurrentHashMap_]は、_Hashtable_の優れた代替品です。 _ConcurrentHashMap_は、複数のスレッドを持つアプリケーションで使用することを検討する必要があります。

5. 結論

この記事では、_HashMap_と_Hashtable_の違いと、1つを選択する必要があるときに留意すべきことを示しました。
いつものように、これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-collections[Github上]です。