ハッシュマップまたはツリーマップを使用する場合
TreeMapを使用して、要素を並べ替える必要があるときに要素を反復処理できることを知っています。しかし、それだけですか?マップを調べたいだけの場合、最適化はありませんか、それとも特定の最適な用途がありますか?
ハッシュテーブルは(通常)O(n)<=T(n)<=O(1)
の複雑さの範囲内で検索操作(ルックアップ)を実行し、平均ケースの複雑さはO(1 + n/k)
になります。ただし、バイナリ検索ツリー(BST)は、O(n)<=T(n)<=O(log_2(n))
の複雑さの範囲内で検索操作(ルックアップ)を実行し、平均ケースの複雑さはO(log_2(n))
です。利点、欠点、操作の時間の複雑さ、コードの複雑さを理解するために、各(およびすべての)データ構造の実装を(ユーザーが)知っている必要があります。
たとえば、ハッシュテーブル内のエントリの数には、衝突のリストが含まれる一定の数のエントリが含まれていることがよくあります(その一部はまったく満たされない場合があります)。一方、ツリーには通常、ノードごとに2つのポインター(参照)がありますが、実装でノードごとに2つ以上の子ノードが許可されている場合、これはさらに大きくなります。複製。 (Java TreeMapはデフォルトの実装では重複を許可しません))
考慮すべき特別なケースもあります。たとえば、特定のデータ構造の要素の数が制限なく増加したり、データ構造の基礎部分の制限に近づいたりした場合はどうなりますか?リバランスまたはクリーンアップ操作を実行する償却操作はどうですか?
たとえば、ハッシュテーブルでは、テーブル内の要素の数が十分に大きくなり、任意の数の衝突が発生する可能性があります。一方、ツリーでは通常、挿入(または削除)後に再バランス手順が必要になります。
したがって、キャッシュのようなものがある場合(例:境界内の要素の数、またはサイズがわかっている場合)、ハッシュテーブルがおそらく最善の策です。ただし、辞書のようなものがある場合(例:1回データを入力して何度も検索した場合)、ツリーを使用します。
ただし、これは一般的な場合のみです(情報は提供されませんでした)。どのデータ構造を使用するかを決定する際に正しい選択をするために、どのように起こるかを理解する必要があります。
コレクションのマルチマップ(範囲検索)またはソートされたフラット化が必要な場合、ハッシュテーブルにすることはできません。
TreeMap
はO(log n)ルックアップ時間(および挿入など)を保証しますが、HashMap
はハッシュコードがキーを分散する場合にO(1)ルックアップ時間を提供します適切に。
エントリをソートする必要がない限り、HashMap
を使い続けます。または、もちろんConcurrentHashMap
があります。それらすべての違いの詳細を思い出すことはできませんが、HashMap
は完全に合理的な「デフォルト」オプションです:)
完全を期すために、さまざまなマップの内部について1か月ほど前にStack Overflowで議論があったことを指摘する必要があります。 この質問のコメント を参照してください。これは、bestsssが喜んでそうするなら、この答えにコピーします。
この2つの最大の違いは、実装で使用される基本的な構造です。
HashMapは、配列とハッシュ関数を使用して要素を保存します。配列内のアイテムを挿入または削除しようとすると、ハッシュ関数はキーを、オブジェクトが保存されている/保存されるべき配列上のインデックスに変換します(競合は無視されます)。ハッシュマップは通常、大量のデータを反復処理する必要がないため非常に高速ですが、すべてのキー/値を新しい配列にコピーする必要があるため、いっぱいになると速度が低下します。
TreeMapsは、ソートされたツリー構造でデータを保存します。これは、これ以上のスペースを割り当ててコピーする必要がないことを意味しますが、操作では、すでに保存されているデータの一部を反復処理する必要があります。時々、大量の構造を変更します。
2つのハッシュマップのうち、ソートが不要な場合は一般にパフォーマンスが向上します。
Add/contains/remove操作にはLinkedHashMap
とほぼ同じ速度であるが、挿入順序も維持するHashMap
もあることを忘れないでください。
HashMapに新しい要素を挿入すると、平均して、TreeMapに要素を挿入するよりもかなり速くなります。要素を並べ替える必要がない限り、HashMapを使用します。