JavaのaHashMap
とaの違いは何ですか?Hashtable
スレッド化されていないアプリケーションでは、どちらがより効率的ですか?
HashMap
とHashtable
Java にはいくつかの違いがあります。
Hashtable
は同期されていますが、HashMap
そうではありません。HashMap
同期されていないオブジェクトは通常、同期されているオブジェクトよりもパフォーマンスが優れているため、これはスレッド化されていないアプリケーションに適しています。
Hashtable
null
キーまたは値 を許可しません。HashMap
1 つのnull
キーと任意の数のnull
値を使用できます。
HashMap のサブクラスの 1 つがであるため、予測可能な反復順序 (デフォルトでは挿入順序) が必要な場合は、をLinkedHashMap
と簡単に交換できます。を使用している場合、これはそれほど簡単ではありません。HashMap
LinkedHashMap
Hashtable
同期は問題にならないので、 をお勧めしHashMap
ます。同期が問題になる場合は、 も参照してくださいConcurrentHashMap
。
回答の多くは、Hashtable が同期されていると述べていることに注意してください。 実際には、これで得られるものはほとんどありません。 同期はアクセサー/ミューテーター メソッドで行われ、2 つのスレッドが同時にマップに追加またはマップから削除するのを停止しますが、実際には追加の同期が必要になることがよくあります。
非常に一般的なイディオムは、"check then put" です。つまり、 内のエントリを探し、Map
まだ存在しない場合は追加します。Hashtable
これは、またはを使用するかどうかにかかわらず、決してアトミック操作ではありませんHashMap
。
同等の同期は、次のHashMap
方法で取得できます。
Collections.synchronizedMap(myMap);
ただし、このロジックを正しく実装するには、フォームの追加の同期が必要です。
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
Hashtable
のエントリ (またはHashMap
によって取得された) を反復処理しても、追加の同期によって が変更されCollections.synchronizedMap
ないように保護しない限り、スレッドセーフではありません。Map
ConcurrentMap
インターフェースの実装(例: ) は、次のようなスレッド セーフな check-then-act セマンティクスConcurrentHashMap
を含めることで、この問題の一部を解決します。
ConcurrentMap.putIfAbsent(key, value);
この質問は、候補者がコレクションクラスの正しい使用法を理解しており、利用可能な代替ソリューションを認識しているかどうかを確認するために、面接でよく尋ねられます。
HashMap
クラスはHashtable
、同期されておらず、nullを許可することを除いて、とほぼ同じです。(HashMap
キーと値としてnull値を許可しますが、sHashtable
は許可しませんnull
)。HashMap
マップの順序が時間の経過とともに一定に保たれることを保証するものではありません。HashMap
同期されているのに対し、Hashtable
は同期されていません。HashMap
はフェイルセーフですが、の列挙子はフェイルセーフではなく、他のスレッドが独自の メソッド以外の要素を追加または削除してマップを構造的に変更した場合Hashtable
にスローされます。ただし、これは保証された動作ではなく、JVMが最善を尽くして実行します。ConcurrentModificationException
Iterator
remove()
いくつかの重要な用語に関する注意:
Hashtable
はオブジェクトのロックを取得する必要があり、他のスレッドはロックが解放されるのを待つことを意味します。set
コレクションを「構造的に」変更しないため、他のスレッドがメソッドを呼び出すことは可能です。ただし、を呼び出す前にset
、コレクションが構造的に変更されている場合IllegalArgumentException
は、スローされます。HashMap
によって同期することができます
Map m = Collections.synchronizeMap(hashMap);
Mapは、列挙オブジェクトを介した反復の直接サポートではなく、コレクションビューを提供します。このセクションで後述するように、コレクションビューはインターフェイスの表現力を大幅に向上させます。マップを使用すると、キー、値、またはキーと値のペアを反復処理できます。Hashtable
3番目のオプションは提供しません。マップは、反復の最中にエントリを削除する安全な方法を提供します。Hashtable
しませんでした。最後に、Mapはインターフェースの小さな欠陥を修正しHashtable
ます。Hashtable
containsが指定された値を含む場合、trueを返すcontainsというメソッドがありHashtable
ます。その名前をHashtable
指定すると、キーがのプライマリアクセスメカニズムであるため、指定されたキーが含まれている場合、このメソッドがtrueを返すことが期待されますHashtable
。マップインターフェイスは、メソッドの名前を変更することにより、この混乱の原因を排除しますcontainsValue
。また、これにより、インターフェイスの一貫性が向上します—containsValue
パラレルcontainsKey
。
HashMap
:Map
ハッシュ コードを使用して配列にインデックスを付けるインターフェイスの実装。
Hashtable
: こんにちは、1998 から電話がありました。彼らは、コレクション API を元に戻したいと考えています。
Hashtable
真剣に、あなたは完全に離れた方が良いです. シングルスレッド アプリの場合、同期の余分なオーバーヘッドは必要ありません。並行性の高いアプリの場合、偏執的な同期により、飢餓、デッドロック、または不要なガベージ コレクションの一時停止が発生する可能性があります。Tim Howland が指摘したように、ConcurrentHashMap
代わりに使用できます。
は、HashTable
Java Collections Framework (JCF) が導入される前はレガシー クラスであり、後でMap
インターフェースを実装するために改良されたことに注意してください。Vector
ともそうだったStack
。
したがって、他の人が指摘したように、JCFには常により良い代替手段があるため、新しいコードでは常にそれらに近づかないでください。
これは、役に立つJava コレクションのチート シートです。灰色のブロックには、従来のクラス HashTable、Vector、および Stack が含まれていることに注意してください。
このチャートを見てください。HashMap
およびとともに、異なるデータ構造間の比較を提供しますHashtable
。比較は正確で、明確で、理解しやすいです。
izbが言ったことに加えて、HashMap
null値を許可しますが、は許可Hashtable
しません。
また、 Javadocsの状態として廃止され、インターフェースに置き換えられたクラスをHashtable
拡張することにも注意してください。Dictionary
Map
Hashtable
に似てHashMap
おり、同様のインターフェイスを備えています。メソッドは同期HashMap
されているため、レガシーアプリケーションのサポートが必要な場合や同期が必要な場合を除いて、を使用することをお勧めします。Hashtables
したがって、マルチスレッドではない場合HashMaps
は、最善の策です。
Hashtable
同期されていますが、HashMap
そうではありません。それはHashtable
より遅くなりHashmap
ます。
シングル スレッド アプリケーションのHashMap
場合は、それ以外の点では機能が同じであるため、使用します。
ここで既に述べた他のすべての重要な側面に加えて、コレクション API (Map インターフェースなど) は、Java 仕様への「最新かつ最高の」追加に準拠するために常に変更されています。
たとえば、Java 5 Map の反復を比較します。
for (Elem elem : map.keys()) {
elem.doSth();
}
対古い Hashtable アプローチ:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
Java 1.8 では、古き良きスクリプト言語のように HashMap を構築してアクセスできることも約束されています。
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
更新:いいえ、1.8 には実装されません... :(
hashtable と hashmap のもう 1 つの重要な違いは、HashMap の Iterator はフェイルファストであるのに対し、Hashtable の列挙子はそうではなく、他のスレッドが Iterator 自身の remove() メソッド以外の要素を追加または削除してマップを構造的に変更した場合に ConcurrentModificationException をスローすることです。しかし、これは保証された動作ではなく、ベスト エフォートで JVM によって実行されます。」
私の情報源: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
HashTableは同期されます。単一のスレッドで使用している場合は、非同期バージョンであるHashMapを使用できます。同期されていないオブジェクトは、多くの場合、パフォーマンスが少し高くなります。ちなみに、複数のスレッドが同時に HashMap にアクセスし、そのうちの少なくとも 1 つのスレッドがマップを構造的に変更する場合は、外部で同期する必要があります。以下を使用して、同期されていないマップを同期されたマップにラップできます。
Map m = Collections.synchronizedMap(new HashMap(...));
HashTable には、null 以外のオブジェクトのみをキーまたは値として含めることができます。HashMap には、1 つの null キーと null 値を含めることができます。
Map によって返されるイテレータはフェイルファストです。イテレータが作成された後、イテレータ自体の remove メソッド以外の方法でマップが構造的に変更された場合、イテレータはConcurrentModificationException
. したがって、同時変更に直面した場合、反復子は、将来の不確定な時点で恣意的で非決定論的な動作を危険にさらすのではなく、迅速かつ明確に失敗します。一方、Hashtable のキーと要素のメソッドによって返される列挙はフェイル ファストではありません。
HashTable と HashMap はJava Collections Frameworkのメンバーです(Java 2 プラットフォーム v1.2 以降、HashTable は Map インターフェースを実装するように改良されました)。
HashTable はレガシー コードと見なされます。ドキュメントでは、スレッドセーフな高度な並行実装が必要な場合は、Hashtable の代わりにConcurrentHashMapを使用することをお勧めします。
HashMap は、要素が返される順序を保証しません。HashTable の場合も同じだと思いますが、完全にはわかりません。それを明確に述べているリソースが見つかりません。
HashMap
Hashtable
また、アルゴリズムにも大きな違いがあります。これまで誰も言及していなかったので、私はそれを取り上げています。HashMap
2 のべき乗サイズのハッシュ テーブルを構築し、それを動的に増やして、任意のバケットに最大で約 8 つの要素 (衝突) があり、一般的な要素タイプの要素を非常にうまく攪拌します。ただし、Hashtable
何をしているのかを知っている場合、実装はハッシュをより細かく制御します。つまり、値のドメインサイズに最も近い素数などを使用してテーブルサイズを修正できます。これにより、HashMap よりもパフォーマンスが向上します。つまり、衝突が少なくなります。場合によっては。
この質問で広く議論されている明らかな違いとは別に、Hashtable はハッシュをより適切に制御できる「手動駆動」の車であり、HashMap は一般的にうまく機能する「自動駆動」の対応物であると考えています。
ここの情報に基づいて、HashMap を使用することをお勧めします。最大の利点は、イテレータを使用しない限り、Java が反復処理中に変更できないことだと思います。
スレッド化されたアプリの場合、パフォーマンス要件に応じて、ConcurrentHashMapを使用しないことがよくあります。
HashMap: java.util パッケージ内で使用可能なクラスであり、要素をキーと値の形式で格納するために使用されます。
Hashtable: コレクション フレームワーク内で認識されている従来のクラスです。
私の小さな貢献:
まず、 と の最も重要な違いは
Hashtable
、がスレッドセーフなコレクションであるのに対し、 はスレッドセーフではないHashMap
ということです。HashMap
Hashtable
Hashtable
との 2 番目の重要な違いHashMap
はパフォーマンスです。HashMap
は同期されていないため、 よりもパフォーマンスが優れていHashtable
ます。
Hashtable
vsの 3 番目の違いHashMap
は、廃止されたクラスであり、Javaの代わりにHashtable
使用する必要があることです。ConcurrentHashMap
Hashtable
Hashtable
同期されていますが、HashMap
そうではありません。HashMap
がフェールセーフであるのに対し、 の列挙子はそうでHashtable
はないことです。反復中にマップを変更すると、わかります。HashMap
null 値を許可しますが、許可しHashtable
ません。HashTableは、jdk のレガシー クラスであり、今後は使用しないでください。その使用法をConcurrentHashMapに置き換えます。スレッドセーフが必要ない場合は、スレッドセーフではありませんが高速でメモリ使用量が少ないHashMapを使用してください。
ハッシュマップとハッシュテーブル
1) Hashtable と Hashmap は java.util.Map インターフェイスを実装します。 2) Hashmap と Hashtable はどちらもハッシュ ベースのコレクションです。ハッシュに取り組んでいます。これらは HashMap と HashTable の類似点です。
1) 最初の違いは、HashMap はスレッド セーフではありませんが、HashTable は ThreadSafe です
。2) HashMap はスレッド セーフではないため、パフォーマンスが優れています。一方、Hashtable のパフォーマンスはスレッドセーフであるため、それほど優れていません。そのため、複数のスレッドが同時に Hashtable にアクセスすることはできません。
Hashtable:
ハッシュテーブルは、キーと値のペアの値を保持するデータ構造です。キーと値の両方に null を許可しません。NullPointerException
null 値を追加すると、 が得られます。同期されています。したがって、それにはコストがかかります。特定の時点でHashTableにアクセスできるスレッドは 1 つだけです。
例:
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));
}
}
ハッシュマップ:
HashMapはHashtableに似ていますが、キーと値のペアも受け入れます。キーと値の両方に null を許可します。そのパフォーマンスは よりも優れ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));
}
}
Java の Hashtable は、Map Interface の存在により廃止された Dictionary クラスのサブクラスであるため、使用されなくなりました。さらに、Hashtable で実行できる Map インターフェイスを実装するクラスで実行できないことはありません。
同期またはスレッドセーフ:
ハッシュマップは同期されていないため、スレッドセーフではなく、適切な同期ブロックがないと複数のスレッド間で共有できませんが、ハッシュテーブルは同期されているためスレッドセーフです。
null キーと null 値:
HashMap では、1 つの null キーと任意の数の null 値を使用できます。Hashtable では、null キーまたは null 値を使用できません。
値の反復:
HashMap の Iterator はフェイルファスト イテレーターですが、Hashtable の列挙子はそうではなく、他のスレッドが Iterator 自身の remove() メソッド以外の要素を追加または削除してマップを構造的に変更した場合、ConcurrentModificationException をスローします。
スーパークラスとレガシー:
HashMap は AbstractMap クラスのサブクラスですが、Hashtable は Dictionary クラスのサブクラスです。
パフォーマンス:
HashMap は同期されないため、Hashtable と比較して高速です。
Java コレクションに関連する例とインタビューの質問とクイズについては、http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-javaを参照してください。
古くて古典的なトピックですが、これを説明するこの役立つブログを追加したいだけです:
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 のメンバーになりました。
HashMap と Hashtable の主な違いの 1 つは、HashMap が非同期であるのに対し、Hashtable は同期されていることです。つまり、Hashtable はスレッドセーフで複数のスレッド間で共有できますが、HashMap は適切な同期なしでは複数のスレッド間で共有できません。Java 5 では、Hashtable の代替であり、Java の Hashtable よりも優れたスケーラビリティを提供する ConcurrentHashMap が導入されました。Synchronized は、ある時点で 1 つのスレッドのみがハッシュ テーブルを変更できることを意味します。基本的に、ハッシュテーブルの更新を実行する前にスレッドがオブジェクトのロックを取得する必要があることを意味し、他のスレッドはロックが解放されるのを待ちます。
HashMap クラスは、null を許可することを除いて、Hashtable とほぼ同じです。(HashMap は null 値をキーと値として許可しますが、Hashtable は null を許可しません)。
HashMap と Hashtable の 3 番目の重要な違いは、HashMap の Iterator はフェイルファスト イテレーターであるのに対し、Hashtable の列挙子はフェイルファスト イテレーターではなく、他のスレッドがイテレーター自身の remove( ) 方法。ただし、これは保証された動作ではなく、ベスト エフォートで JVM によって実行されます。これは、Java における Enumeration と Iterator の重要な違いでもあります。
Hashtable と HashMap のもう 1 つの注目すべき違いは、シングル スレッド環境で使用する場合、スレッド セーフと同期のため、Hashtable は HashMap よりもはるかに遅いことです。したがって、同期が必要なく、HashMap が 1 つのスレッドでのみ使用される場合は、Java で Hashtable を実行します。
HashMap は、マップの順序が時間の経過とともに一定に保たれることを保証しません。
HashMap は次の方法で同期できることに注意してください。
Map m = Collections.synchronizedMap(hashMap);
要約すると、Java の Hashtable と HashMap にはスレッドセーフと速度などの大きな違いがあり、これに基づいて、スレッドセーフが絶対に必要な場合にのみ Hashtable を使用します。Java 5 を実行している場合は、Java で ConcurrentHashMap を使用することを検討してください。
HashMaps を使用すると、同期の自由が得られ、デバッグがはるかに簡単になります
HashMap は、要素をキーと値の形式で格納するために使用されるクラスです。スレッドセーフではありません。同期されていないため.Hashtableが同期されているため.Hashmapはnullを許可しますが、hastableはnullを許可しません。