22

add()は重複を無視することになっていると思いましたが、出力に重複があります。重複を保存しないようにするにはどうすればよいですか?

また、優先キューが2つの要素が重複しているかどうかを確認する方法についても知りたいです。コンパレータequalsを使用していると思いますが、確認したいだけです。

ありがとう

4

4 に答える 4

19

PriorityQueueJavadocの一部を次に示します。

このキューは、使用されるコンストラクターに応じて、自然な順序(Comparableを参照)またはComparatorのいずれかに従って指定された、構築時に指定された順序に従って要素を順序付けます。

そうです、PriorityQueueはComparatorを使用するか(コンストラクター引数として指定した場合)、compareTo(...)メソッドを使用します(要素はComparableインターフェイスを実装する必要があります)。

PriorityQueueは重複を許可します。したがって、それを回避したい場合は、独自のバージョンのQueueを実装する必要があります。非常にエレガントな方法を見つけることができます。その方法は、85ページの「効果的なJava」にあります。または、PriorityQueueクラスを拡張し、addメソッドをオーバーライドすることもできます(これは、contains(...)チェックを配置するのに最適な場所です)。

于 2012-05-06T10:26:02.153 に答える
10

JavaのAPriorityQueueには、重複する要素に関する制限はありません。2つの同一のアイテムが同時に優先キューに存在しないようにする場合、最も簡単な方法はSet、優先キューと並行して別個のものを維持することです。優先度付きキューに要素を挿入するたびに、セットに要素がすでに含まれているかどうかを確認し、含まれていない場合は、セットと優先度付きキューの両方に追加できます。優先キューから要素を削除するときはいつでも、その要素もセットから削除してください。

または、優先度付きキューで実行する予定の操作と、ケースでの同等性の定義方法によっては、TreeSet代わりに単一の操作に置き換えることができる場合があります。これにより、必要なすべての重要な操作を実行できるようになります。優先キューへのアクセスは、さらに重複を許可しません。

于 2012-05-06T10:20:33.987 に答える
6

次のサンプル実装

import java.util.PriorityQueue;

public class NoDuplicates<E> extends PriorityQueue<E> 
{
    @Override
    public boolean offer(E e) 
    {
        boolean isAdded = false;
        if(!super.contains(e))
        {
            isAdded = super.offer(e);
        }
        return isAdded;
    }
    public static void main(String args[])
    {
        PriorityQueue<Integer> p = new NoDuplicates<Integer>();
        p.add(10);
        p.add(20);
        p.add(10);
        for(int i =0;i<=2;i++)
        {
            System.out.println(p.poll());
        }
        
    }
}

結果は

10
20
null

これは、重複する要素が追加されていないことを示しています10

于 2012-10-21T08:53:02.323 に答える
3

重複を無視するのはセットだけです。リストとキューはそうではありません。(LinkedListはキューです)

重複を削除したい場合は、take()のエントリが前のものと同じであるかどうかを確認し、無視することができます。好きなように比較できます。;)

于 2012-05-06T10:56:18.393 に答える