web-dev-qa-db-ja.com

arraylistでキューを使用する場合

ArrayListでQueueを使用する1つの基本的な引数は、QueueがFIFOの動作を保証することです。

ただし、ArrayListに10個の要素を追加し、次に0番目の要素から開始して要素を反復処理すると、追加されたのと同じ順序で要素が取得されます。したがって、本質的には、FIFO動作を保証します。

従来のArrayListと比較して、Queueの何が特別なのですか?

21
Victor

Queueインスタンスを指定した場合、remove()を繰り返し呼び出すことにより、FIFOの順序で要素を取得することになります。 ArrayListインスタンスの場合、そのような保証はできません。

例として次のコードを見てください:

        ArrayList<Integer> list = new ArrayList<Integer>();
    list.add(5);
    list.add(4);
    list.add(3);
    list.add(2);
    list.add(1);


    list.set(4,5);
    list.set(3,4);
    list.set(2,3);
    list.set(1,2);
    list.set(0,1);

    System.out.println(list);

私が今あなたにこのリストを与えるとしたら、私の0から4までの繰り返しでは、要素をFIFOの順序で取得できません。

また、もう1つの違いは抽象化です。 Queueインスタンスを使用すると、インデックスについて心配する必要がなくなります。これにより、ArrayListが提供する必要のないものがすべてある場合に、これを考えることが容易になります。

15
Lee Martie

javadoc here を見ることができます。主な違いは、Listを使用すると、いつでも任意の要素を確認できます。キューでは、「次の」キューのみを確認できます。

それを実際の待ち行列、または食料品店のレジの列と考えてください。途中または最後の人に次に支払うように頼むのではなく、常に前にいる人/最も長く待っている人に常に尋ねます。

一部のリストがキューであることは注目に値します。たとえば LinkedList を見てください。

16
Daniel Kaplan

キューに課せられる制限(FIFO、ランダムアクセスなし)は、ArrayListと比較して、データ構造をより最適化し、同時実行性を高め、必要に応じてより適切でクリーンな設計にすることができます。

最適化と並行性に関して、コンシューマーがキューを消費している間にプロデューサーがキューを埋める一般的なシナリオを想像してください。これにArrayListを使用した場合、単純な実装では、最初の要素を削除するたびに、他のすべての要素を下に移動するために、ArrayListでシフト操作が発生します。これは、リストがシフト操作全体の間ロックされるため、特に並行実装では非常に非効率的です。

デザインに関しては、FIFOの方法でアイテムにアクセスする場合、キューを使用するとその意図が自動的に伝達されますが、リストはそうではありません。この明確な伝達により、コードをより簡単に理解できます。 、そしてコードをより堅牢にし、バグのないものにする可能性があります。

7
Trevor Freeman

違いは、キューの場合、FIFOの順序で要素をプルすることが保証されていることです。ArrayListの場合、要素が追加された順序がわかりません。使用方法によっては、 ArrayListにFIFO順序付けを適用できます。キューのラッパーを設計して、必要な要素をプルできるようにすることもできます。

私が作ろうとしている点は、これらのクラスは何か上手になるように設計されているということです。そのためにそれらを使用する必要はありませんが、それはそれらがそのために設計および最適化されているものです。キューは要素の追加と削除には非常に適していますが、それらを検索する必要がある場合は不適切です。一方、ArrayListsは、要素を追加するのが少し遅くなりますが、ランダムアクセスが容易になります。ほとんどのアプリケーションでは表示されませんが、どちらを選択するかによってパフォーマンスが低下することがよくあります。

1
specs

はい!

キューでpoll()メソッドとpeek()メソッドを使用して、値を返すだけでなく、それぞれ削除し、ヘッド要素を調べました。また、これらのメソッドは、操作が失敗して例外がスローされない場合に特別な値nullを提供します。 remove()メソッドを使用すると、nosuchelement例外がスローされます。

参照:docs.Oracle.com

1
Ankish

ランダムプロセスがarraylistをランダムに更新し、それらをfifoで処理することになっている状況を考えてみますか?

それを行う方法は絶対にありませんが、データ構造をarraylistからqueueに変更する必要があります

たとえば、Queueメソッドpoll()およびremove()は、要素を取得してキューから削除します。

Queueインターフェイス(PriorityQueue)の一部の実装では、要素に優先度を設定し、この優先度のおかげで要素を取得できます。これは、最後のケースでのFIFO動作よりはるかに多くなります。

0
eternay