私はJavaのArrayDequeがJavaのLinkedListよりも優れている理由が両方ともDequeインターフェースを実装しているので、理解しようとしています。
コードでArrayDequeを使用している人はほとんどいません。誰かがArrayDequeの実装方法にもっと光を当てれば、役に立つでしょう。
理解できれば、自信を持って使用できます。 JDK実装がヘッドリファレンスとテールリファレンスを管理する方法について明確に理解できませんでした。
リンクされた構造は、各要素のキャッシュミスで反復する最悪の構造である可能性があります。その上、彼らはずっと多くのメモリを消費します。
両端の追加/削除が必要な場合、ArrayDequeはリンクリストよりもはるかに優れています。循環キューの場合、各要素のランダムアクセスもO(1)です。
リンクされたリストの唯一のより良い操作は、反復中に現在の要素を削除することです。
LinkedList
の主なパフォーマンスのボトルネックは、両端キューのいずれかの端にプッシュするたびに、実装が基本的にJVM/OSを含む新しいリンクリストノードを割り当て、それが高価であるという事実だと思います。また、いずれかの端からポップするたびに、LinkedList
の内部ノードがガベージコレクションの対象になります。これは、背後でより多くの作業が行われます。また、リンクリストノードはあちこちに割り当てられるため、CPUキャッシュを使用してもあまりメリットはありません。
興味があれば、ArrayList
またはArrayDeque
に要素を追加すると、償却された一定の時間で実行されるという証拠があります。 this を参照してください。
ArrayDeque
はJava 6で新しく追加されたため、多くのコード(特に以前のJavaバージョンとの互換性を保とうとするプロジェクト)は使用しません。
挿入する各アイテムにノードを割り当てていないため、場合によっては「より良い」です。代わりに、すべての要素は巨大な配列に格納され、いっぱいになるとサイズが変更されます。
ArrayDequeの要素へのアクセスは、要素へのアクセスにO(1)を使用したLinkedListと比較して常に高速です。リンクリストでは、O(N)が最後の要素を見つけるのに必要です。
ArrayDequeは、リンクリストとは異なり、次のノードを追跡する必要がないため、メモリ効率に優れています。
Javaドキュメントごとに、引用されています
ArrayDequeは、Dequeインターフェイスのサイズ変更可能な配列の実装です。配列両端キューには容量制限がありません。使用をサポートするために必要に応じて成長します。これらはスレッドセーフではありません。外部同期がない場合、複数のスレッドによる同時アクセスはサポートされません。ヌル要素は禁止されています。このクラスは、スタックとして使用する場合はStackよりも高速であり、キューとして使用する場合はLinkedListよりも高速です。
ベンチマーク これら2つのうち、ArrayDequeの方が高速であることが証明されています。
ArrayDeque<E>
とLinkedList<E>
は両方とも実装されていますDeque<E>
インターフェイスですが、ArrayDequeは基本的にオブジェクト配列を使用しますE[]
そのオブジェクト内にあるため、通常は、head要素とtail要素を見つけるためにインデックスを使用します。
Wordでは、Deque(Dequeのすべてのメソッドを使用)と同様に機能しますが、配列のデータ構造を使用します。どちらが優れているかに関しては、それらをどのように、どこで使用するかに依存します。