61

List、Map、または Set などの Java Collection インターフェースのさまざまな実装を選択するための適切な経験則がある人はいますか?

たとえば、Vector または ArrayList、Hashtable または HashMap を使用するのが一般的にどのような場合で、どのような場合に適しているのでしょうか?

4

11 に答える 11

24

上記の回答から、リスト、セット、マップの違いを知っていると思います。それらの実装クラスから選択する理由は別のことです。例えば:

リスト

  1. ArrayListは取得は高速ですが、挿入は低速です。これは、多くの読み取りを行うが、多くの挿入/削除を行わない実装に適しています。データを1つの連続したメモリブロックに保持するため、拡張が必要になるたびに、配列全体がコピーされます。
  2. LinkedListの取得は遅くなりますが、挿入は速くなります。これは、多くの挿入/削除を行うが、多くの読み取りを行わない実装に適しています。アレイ全体を1つの連続したメモリブロックに保持するわけではありません。

セットする:

  1. HashSetは反復の順序を保証しないため、セットの中で最速です。オーバーヘッドが高く、ArrayListよりも遅いため、ハッシュ速度が要因になる場合は、大量のデータを除いて使用しないでください。
  2. TreeSetはデータの順序を維持するため、HashSetよりも低速です。

Map: HashMapとTreeMapのパフォーマンスと動作は、Setの実装と並行しています。

VectorとHashtableは使用しないでください。これらは、新しいコレクション階層がリリースされる前の同期された実装であるため、低速です。同期が必要な場合は、Collections.synchronizedCollection()を使用します。

于 2008-09-07T14:17:46.243 に答える
16

私は常に、次のようなユースケースに応じて、ケースバイケースでこれらの決定を下しました。

  • 注文を残す必要がありますか?
  • nullのキー/値はありますか?重複?
  • 複数のスレッドからアクセスされますか
  • キーと値のペアが必要ですか
  • ランダムアクセスが必要ですか?

次に、便利な第5版のJavaを簡単に説明し、約20個のオプションを比較します。第5章には、何が適切かを理解するのに役立つ小さな表があります。

わかりました。たぶん、単純なArrayListまたはHashSetがトリックを実行することをカフから知っていれば、すべてを調べることはしません。;)しかし、私の意図した使用法についてリモートで複雑なことがあれば、あなたは私が本の中にいるに違いありません。ところで、Vectorは「古い帽子」であるはずですが、私は何年も使用していません。

于 2008-09-07T14:03:48.913 に答える
12

理論的には便利なBig-Oh のトレードオフがありますが、実際にはこれらが問題になることはほとんどありません。

実世界のベンチマークでは、大きなリストや「前面近くの挿入が多い」などの操作でも優れArrayListたパフォーマンスを発揮します。LinkedList学者は、実際のアルゴリズムには漸近曲線を圧倒する定数要素があるという事実を無視しています。たとえば、リンクされたリストでは、ノードごとに追加のオブジェクト割り当てが必要になるため、ノードの作成が遅くなり、メモリ アクセス特性が大幅に低下します。

私のルールは次のとおりです。

  1. 常に ArrayList と HashSet と HashMap から始めます (つまり、LinkedList や TreeMap ではありません)。
  2. 型宣言は常にインターフェイス (つまり、List、Set、Map) である必要があるため、プロファイラーまたはコード レビューでそうでないことが証明された場合は、何も壊さずに実装を変更できます。
于 2008-09-07T15:26:05.567 に答える
8

あなたの最初の質問について...

リスト、マップ、セットは異なる目的を果たします。http://java.sun.com/docs/books/tutorial/collections/interfaces/index.htmlでJavaコレクションフレームワークについて読むことをお勧めします。

もう少し具体的に言うと:

  • 配列のようなデータ構造が必要で、要素を反復処理する必要がある場合は、Listを使用します
  • 辞書のようなものが必要な場合は、マップを使用してください
  • 何かがセットに属するかどうかを判断するだけでよい場合は、セットを使用します。

2番目の質問について...

VectorとArrayListの主な違いは、前者は同期され、後者は同期されないことです。Java ConcurrencyinPracticeの同期について詳しく読むことができます。

Hashtable(Tは大文字ではないことに注意してください)とHashMapの違いは類似しており、前者は同期され、後者は同期されません。

どちらかの実装を優先するための経験則はありません。それは本当にあなたのニーズに依存します。

于 2008-09-07T14:03:48.180 に答える
5

ソートされていない場合、最良の選択は 10 回中 9 回以上、ArrayList、HashMap、HashSet になります。

Vector と Hashtable は同期されているため、少し遅くなる可能性があります。同期された実装が必要になることはめったにありません。実装を行う場合、それらのインターフェイスは、同期が役立つほど十分にリッチではありません。Map の場合、ConcurrentMap は追加の操作を追加して、インターフェイスを便利にします。ConcurrentHashMap は、ConcurrentMap の適切な実装です。

LinkedList は、ほとんど良い考えではありません。多くの挿入と削除を行っている場合でも、位置を示すためにインデックスを使用している場合は、正しいノードを見つけるためにリストを反復処理する必要があります。ほとんどの場合、ArrayList の方が高速です。

Map と Set の場合、ハッシュ バリアントはツリー/ソートよりも高速です。ハッシュ アルゴリズムは O(1) のパフォーマンスを持つ傾向がありますが、ツリーは O(log n) になります。

于 2008-09-07T15:18:39.530 に答える
2

リストは重複アイテムを許可しますが、セットは1つのインスタンスのみを許可します。

ルックアップを実行する必要があるときはいつでも、マップを使用します。

特定の実装では、マップとセットの順序を維持するバリエーションがありますが、主に速度に依存します。私は適度に小さいリストにはArrayListを使用し、適度に小さいセットにはHashSetを使用する傾向がありますが、多くの実装があります(自分で作成したものを含む)。HashMapはマップではかなり一般的です。「適度に小さい」以上のものはすべて、アルゴリズム的にはるかに具体的になるように、メモリについて心配し始める必要があります。

このページには、多くのアニメーション画像と、ハードナンバーに興味がある場合はLinkedListとArrayListをテストするサンプルコードがあります。

編集:次のリンクが、これらのものが実際にはツールボックス内の単なるアイテムであることを示していることを願っています。ニーズが何であるかを考える必要があります。Commons-CollectionsバージョンのMapList、およびSetを参照してください。

于 2008-09-07T14:06:20.950 に答える
2

まあ、それはあなたが必要とするものに依存します。一般的なガイドラインは次のとおりです。

リストは、データが挿入順に保持され、各要素にインデックスが付けられたコレクションです。

Setは重複のない要素の袋です (同じ要素を再挿入しても追加されません)。データには順序の概念がありません。

マップデータ要素にアクセスして、そのキーで書き込みます。これは、任意の可能なオブジェクトである可能性があります。

ここに画像の説明を入力 帰属: https://stackoverflow.com/a/21974362/2811258

Java コレクションの詳細については、この記事を参照してください

于 2019-05-30T08:04:29.180 に答える
1

ブルース・エッケルのJavaでの思考は非常に役に立ちました。彼はさまざまなコレクションを非常によく比較しています。私は彼が公開した図を保持していて、クイックリファレンスとして私の立方体の壁に継承されたheirachyを示していました。私が提案することの1つは、スレッドセーフを念頭に置くことです。パフォーマンスは通常、スレッドセーフではないことを意味します。

于 2008-09-07T14:30:16.637 に答える