17

PersistentHashMap、PersistentArrayMap、PersistentTreeMap、および PersistentStructMap の違いを理解しようとしています。

また、それを使用する{:a 1}と PersistentArrayMap が得られますが、オブジェクトまたはキー以外のものを与えると、これを他のものに変更できますか?

4

2 に答える 2

18

リストした 4 つの実装は、次の 3 つのグループに分類されます。

  1. "literal" :PersistentArrayMapおよびPersistentHashMap: マップ リテラルを処理するときに使用される基本的なマップ タイプ (コンストラクター関数も、重複キーの処理に関して異なる動作で使用できますが、Clojure 1.5.x では、リテラルは重複キーを検出すると例外をスローしますが、コンストラクター関数は左のように機能します-to-right の繰り返しconjing; この動作はバージョンごとに進化しています)。配列マップは、特定の数のエントリ (9 IIRC) を超えると、ハッシュ マップに昇格します。配列マップが存在するのは、小さいマップの方が高速であるためです。また、ハッシュ マップに昇格する前にエントリを挿入順に保持するという点でも、ハッシュ マップとは異なります (次を使用できます)。clojure.core/array-map任意に大きな配列マップを取得します。これは、挿入順序トラバーサルの恩恵を受けることが本当にわかっていて、マップが大きすぎず、おそらく通常のしきい値を少し超えない場合に役立ちます。注意。このような大きすぎる配列マップに続くassocは、ハッシュ マップを返します)。配列マップは、キーと値がインターリーブされた配列を使用します。PHM は、Phil Bagwell のハッシュ配列マップ トライの永続的なバージョンを使用し、ハッシュの衝突に別のチェーンを使用し、ほぼ空で少なくとも半分がいっぱいのノードに別のノード タイプを使用します。これは、Clojure で最も複雑なデータ構造です。

  2. sorted :PersistentTreeMapインスタンスは、特別なリクエスト (sorted-mapまたはの呼び出しsorted-map-by) によってのみ作成されます。これらは赤黒ツリーとして実装され、特定の順序でエントリを維持します。これは、 で作成されたcompare場合はデフォルトのコンパレータ、 で作成されたsorted-map場合はユーザー指定のコンパレータで指定されますsorted-map-by

  3. special-purpose, おそらく deprecated :PersistentStructMapあまり頻繁には使用されず、ほとんどの場合、レコードを支持して非推奨と見なされていますが、公式の非推奨通知があったかどうかは今のところ思い出せません. 当初の目的は、頻繁に使用される特定のキーに特に高速にアクセスできるマップを提供することでした。これは、フィールド アクセスにキーワードを使用する場合 (演算子の位置: にキーワードを使用) にレコードを使用して実行できるようになりまし(:foo instance-of-some-record-with-field-foo)=

これら 4 つの組み込みマップ タイプはすべて、同じ「等価パーティション」に分類されます。つまり、上記の 4 つのクラスのいずれかの 2 つのマップは、それらが同じキーを含む場合 (およびその場合にのみ) 等しくなります (Clojure の=) 対応する値は同じです。上記の 3. で述べたように、レコードはマップに似ていますが、各レコード タイプは独自の等価パーティションを形成します。

于 2013-05-13T07:23:05.747 に答える
5

それらは永続マップの異なる実装です (それらはすべて拡張されますAPersistentMap)。したがって、 PersistentArrayMap配列を基になるデータ構造として使用して永続的なマップを実装し、同様に他の実装では異なる基になるデータ構造を使用します。

異なる実装の理由は、異なる状況で異なる利点を提供するためです (実装の効率は基礎となるデータ構造に依存するため)。

開発者の観点からは、抽象化されているため、それらを直接使用するのではなく、代わりにAPersistentMap抽象クラスまたはIPersistentMapインターフェイスを操作する必要があります (特定のケースで型チェックなどが必要な場合)。

マップ内の要素の数に応じて、さまざまな実装が使用されます。

(type (into {} (map #(-> [% %]) (range 5))))
=> PersistentArrayMap
(type (into {} (map #(-> [% %]) (range 10))))
=> PersistentHashMap
于 2013-05-13T06:55:10.933 に答える