4

次のテストを行って、

PriorityBlockingQueue<String> pq = new PriorityBlockingQueue<>(2);
     pq.put("Sing");
     pq.put("Sing2");
     pq.put("Sing3");
     pq.put("Sing4");
     pq.put("Sing10");
     pq.put("Sing11");
     pq.put("Sing12");
     pq.put("Sing13");
     for (String s1: pq)
     {
         System.out.print(s1 +" ");
     }

私が得る結果は次のとおりです。

 Sing Sing10 Sing11 Sing13 Sing2 Sing3 Sing12 Sing4

構築時にコンパレーターが指定されていない場合、 APIがどのようにそれらを自然な順序で並べ替える必要があるかを説明します。ただし、ご覧のとおり、結果はまったく順序付けられていません。

次に、設定した初期容量は 2 でした。境界が実際に設定されていないのに、なぜそのようなオプションがあるのでしょうか? ポイントは何ですか?私はAPIがそれが無制限の優先度キューであることを指定していることを理解していますが、コンストラクターが初期容量を設定できないのに、なぜコンストラクターを作成するのですか?

だから基本的に私は2つの質問があります:

1)投稿された上記の結果の順序が要素の自然な順序に従わないのはなぜですか?

2)実際に境界を設定しないパラメーター「初期容量」を持つコンストラクターを持つ目的は何ですか。LinkedBlockingQueueでは境界を設定するので妥当ですが、PriorityBlockingQueue では発生しません。

前もって感謝します。

4

4 に答える 4

10

たとえば、poll、remove、peek、または take を使用して head にアクセスする場合、順序は保証されますが、反復する場合は保証されません。

メソッド iterator() で提供される Iterator は、優先キューの要素を特定の順序でトラバースすることは保証されていません。

これにより、期待される出力が得られます。

String s;
while ((s = pq.poll()) != null) {
    System.out.println(s);
}

出力:

Sing
Sing10
Sing11
Sing12
Sing13
Sing2
Sing3
Sing4

実際に境界を設定しないパラメーター「初期容量」を持つコンストラクターを持つ目的は何ですか。

初期容量に制限はありません。キューは配列によって支えられています - 初期容量を設定することで、不必要な配列のサイズ変更を避けることができます (ArrayList のコンストラクタと同様)。

于 2013-07-18T14:41:27.670 に答える
5

javadoc は次のように述べています。

メソッド iterator() で提供される Iterator は、特定の順序で PriorityBlockingQueue の要素をトラバースすることが保証されていません。順序付けされたトラバーサルが必要な場合は、Arrays.sort(pq.toArray()) の使用を検討してください。

を使用すると、要素が順番に取得されますpeek()/poll()/take()。しかし、反復するときはそうではありません。

2 番目の質問に答えるには、キューはオブジェクトの配列として内部的に実装されます。初期容量を設定すると、キューが大きくなり、要素の数が容量を超えたときに、配列のコピーが多すぎるのを防ぐことができます。ArrayList のように。

于 2013-07-18T14:40:17.003 に答える
1

初期容量は、要素を格納するコンテナーが @-) で初期化されるサイズです。要素が追加されると、容量は自動的に増加します。コンテナーのサイズを拡張するためのコストは、成長ポリシー (基になるコンテナーによって定義される) によって異なります。

PriorityBlockingQueue定義による無制限のブロッキング キューです。パラメータ「初期容量」を持つこのようなコンストラクタを持つ目的は、実際のユースケースにとって意味のある値で基礎となるコンテナを初期化することです。これは、 の実装者が予見することはできませんPriorityBlockingQueue

LinkedBlockingQueueその定義により、オプションで制限されたブロッキング キューです。したがって、パラメーターには、設定されている場合、上限として機能する関数があります。

于 2013-07-18T14:48:28.133 に答える
0

このリンクを確認してください

メソッド iterator() で提供される Iterator は、特定の順序で PriorityBlockingQueue の要素をトラバースすることが保証されていません。順序付けされたトラバーサルが必要な場合は、Arrays.sort(pq.toArray()) の使用を検討してください。また、drainTo メソッドを使用して、優先順位に従って一部またはすべての要素を削除し、別のコレクションに配置することもできます。

于 2013-07-18T14:46:16.393 に答える