どのJavaコレクションを使用すればよいですか?


127

この質問では、C ++ 11で標準ライブラリコンテナーを効率的に選択するにはどうすればよいですか?C ++コレクションを選択するときに使用する便利なフローチャートです。

これは、どのコレクションを使用すればよいかわからない人にとっては便利なリソースだと思ったので、Javaの同様のフローチャートを見つけようとしましたが、見つけることができませんでした。

Javaでプログラミングするときに使用する適切なコレクションを選択するのに役立つリソースと「チートシート」はありますか?どのようなリスト、セット、マップの実装を使用すべきかを人々はどのように知るのでしょうか?


『Java Generics and Collections(Naftalin&Wadler)』という本には、これに関する章があります。
Christophe Roussy

回答:


292

同様のフローチャートが見つからなかったので、自分で作成することにしました。

このフローチャートは、同期アクセス、スレッドセーフティなどのレガシーコレクションなどを対象としていませんが、3つの標準セット、3つの標準マップ、2つの標準リストを対象としています。

ここに画像の説明を入力してください

この画像はこの回答のために作成され、クリエイティブ・コモンズの表示4.0国際ライセンスの下でライセンスされています。最も単純な帰属は、この質問またはこの回答のいずれかにリンクすることです。

その他の資料

おそらく、最も有用な他のリファレンスは、各コレクションを説明するoracleドキュメントの次のページです。

HashSetとTreeSet

いつ、HashSetまたはTreeSetここで使用するかについての詳細な議論があります: ハッシュセットとツリーセット

ArrayListとLinkedList

詳細な説明:ArrayListよりもLinkedListを使用する場合


いいね!しかし、私はあなたのLinkedListvsのArrayList決定に同意しなければなりません。まず、リストのサイズが大きい場合は、それLinkedListが望ましいです。LinkedList要素ごとのオーバーヘッドがあるため、メモリ消費の点ではに比べて漸近的に劣りArrayListます。また、ほとんどのアクセスがリストの最後にあるArrayList場合は、一定時間のランダム要素アクセスを提供するので、が推奨されます。アクセスnの番目の要素は、LinkedListあるO(n)操作。...実際、リンクされたリストを使用する決定は、かなりのはずです。、常に「いいえ。」こと
マットボール

2
@MattBallほとんどの部分であなたに同意します。ただし、Java LinkedListは二重リンクリストであるため、最初と最後のアクセスはどちらも高速です。上記の3つすべての質問のブランチでは、私がを使用する前に「はい」と答える必要があることに注意しLinkedListてください。つまり、ほとんどの場合、答えは「いいえ」であることに同意します。キューやデキューのようなもので、リスト領域の最後に常に追加したり削除したりするものは、の良いユースケースですLinkedList
Tim B

@MattBallメモリ使用量は、LinkedList要素ごとにより多くのメモリを使用するので、はるかにトリッキーな状況です... ArrayListメモリを解放することはありません。つまり、リストが巨大なサイズになることがありますが、通常は小さい場合、ArrayListメモリパフォーマンスが低下します。Listそれ自体のメモリオーバーヘッドは、通常は(常にではありませんが)、それに含まれる要素のオーバーヘッドと比較して小さいです。
ティムB

Map<K,V>の一部ではありませんjava.util.collection
Mehraj Malik

@MehrajMalikうーん、ラベル付けがあいまいです。java.util内のコレクションを意味しました。つまり、java.util。*ここにコレクション名を挿入*
Tim B

66

主要な非並行、非同期のコレクションの概要

Collection:「要素」と呼ばれる、項目の順序付けされていない「バッグ」を表すインターフェース。「次の」要素は未定義(ランダム)です。

  • SetCollection重複のないを表すインターフェース。
    • HashSet:にSet裏打ちされたHashtable。順序が重要ではない場合の最速かつ最小のメモリ使用量。
    • LinkedHashSet:A HashSetとリンクリストを追加して、要素を挿入順に関連付けます。「次の」要素は、次に挿入された要素です。
    • TreeSetSet要素がaによって順序付けられるAComparator(通常は自然順序付け)。最も低速で最大のメモリ使用量ですが、コンパレータベースの順序付けに必要です。
    • EnumSet:非常に高速で効率的 Set単一の列挙型用にカスタマイズされたもの。
  • List:を表すインターフェース Collection要素が順序付けられ、それぞれがその位置を表す数値インデックスを持つを。ゼロは最初の要素であり(length - 1)、最後です。
    • ArrayListList配列に裏打ちされた配列。配列には、少なくとも要素数(リストの「サイズ」)と同じ長さ(「容量」と呼ばれます)があります。サイズが容量を超えると((capacity + 1)-th要素が追加されると)、配列は新しい容量で再作成され(new length * 1.5)ます-を使用するため、この再作成は高速System.arrayCopy()です。要素を削除および挿入/追加するには、隣接するすべての要素(右側)をそのスペースに移動するか、そのスペースから移動する必要があります。要素(element-zero-address + desired-index * element-size)の場所を見つけるための計算のみが必要なため、任意の要素へのアクセスは高速です。ほとんどの場合ArrayListはに優先しますLinkedList
    • LinkedListListそれぞれがその「前の」隣と「次の」隣にリンクされているオブジェクトのセットに支えられています。AはLinkedListまた、あるQueueDeque。要素へのアクセスは、最初または最後の要素から始まり、目的のインデックスに到達するまでトラバースします。トラバーサルを介して目的のインデックスに到達した後の挿入と削除すぐ隣のリンクのみを再マッピングして、新しい要素をポイントするか、現在削除されている要素をバイパスするのは簡単です。
  • Map:を表すインターフェース Collection各要素が識別用の「キー」を持つ場所を。各要素はキーと値のペアです。
    • HashMap:A Mapキーは順不同、とに裏打ちされていますHashtable
    • LinkedhashMap:キーは次の順序で並べられます 挿入順に並べられます。
    • TreeMapMapキーがaによって順序付けられるAComparator(通常は自然な順序で)順序付けられる場所です。
  • Queue:を表すインターフェース Collection通常、要素が一方の端に追加され、もう一方から削除される場所(FIFO:先入れ先出し)。
  • Stack:を表すインターフェース Collection通常、要素が同じ端から追加(プッシュ)され、削除(ポップ)さ where要素(LIFO:後入れ先出し)。
  • Deque:「ダブルエンドキュー」の略で、通常は「デッキ」と発音されます。リンクされたリストで、通常は両端(中央ではなく)にのみ追加され、そこから読み取られます。

基本的なコレクション図:

図

要素の挿入ArrayListとandの比較LinkedList

図


2
どこでも手に入れることができる簡単な夏のベスト:)
roottraveller 2016年

11

さらに簡単な画像はこちらです。意図的に簡略化!

  1. コレクションは、「要素」(同じタイプの)と呼ばれるデータを保持するものです。より具体的なものは想定されていません。

  2. リストは、各要素がインデックスを持つデータのインデックス付きコレクションです。配列のようなものですが、より柔軟です。

    リスト内のデータは挿入の順序を維持します。

    一般的な操作:n番目の要素を取得します。

  3. セット要素のバッグであり、各要素は一度だけです(要素はequals()メソッドます)。

    セット内のデータは、単に知っているほとんどが保存されているどのようなデータがあります。

    一般的な操作:要素がリストに存在するかどうかを確認します。

  4. マップはリストのようなものですが、整数インデックスで要素にアクセスする代わりに、任意のオブジェクトである keyで要素にアクセスします。PHPの配列のように:)

    Mapのデータはキーで検索できます。

    一般的な操作:IDで要素を取得します(IDはintリストの場合だけでなく、任意のタイプです)。

違い

  • SetとMap:Set では自分でデータを検索し、Mapではキーで検索します

  • リストとマップ:リストでは要素にintインデックス(リスト内の位置)でアクセスし、マップでは任意のタイプのキー(通常はID)でアクセスします。

  • リストとセット:リストでは要素はその位置によってバインドされ、複製できますが、セットでは要素は「存在する」(存在しない)だけで、一意です(の意味でequals()、またはのcompareTo()場合SortedSet


1

それは簡単です:キーがマップされた値を格納する必要がある場合はMapインターフェースに移動し、そうでない場合は重複する可能性のある値にListを使用し、コレクション内で重複する値が必要ない場合は最終的にSetインターフェースを使用します。

ここにフローチャートなどを含む完全な説明http://javatutorial.net/choose-the-right-java-collectionがあります


1

地図

を選択する場合Map、Java 11にバンドルされている10の実装のそれぞれの機能を要約したこの表を作成しました。

Java 11のマップ実装の表、それらの機能の比較



-2

どのJavaコレクションを使用すればよいですか?

それはあなたが解決しようとしている問題やあなたが持っているどんな要件に依存します。

例:

  1. 要素を格納する際に要素を並べ替えますか?ハッシュセット
  2. (Key、Value)のペアを保存しますか?HashMap
  3. 挿入時の要素の順序を保持しますか?ArrayList、LinkedList
  4. (Key、Value)ペアのキーをソートしますか?- 強いテキスト
  5. 問題を解決するためにスタックを実装しますか?- スタック
  6. FIFO(先入れ先出し)アクセスが必要ですか?- キュー
  7. UNIQUE要素のみを保存しますか?- HashSetの
  8. (Key、Value)の保存中にキーを「Null」として許可しますか?- HashMapの
  9. (Key、Value)ペアにNULL値はありませんか?ハッシュ表

でも、との強いテキスト項目4中には、たとえば、置き換えられConcurrentSkipListMapの(K、V)ティム・Bさんにこの答えのアドオン何、決定グラフを aliteralmindさんに、「ショートリストの説明」
greybeard

最初のポイントは、挿入順序が維持されていなくても、HashSetはデータをソートしないことです。TreeSetで変更する必要があります
Saurabh Mishra
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.