2011-11-09 1 views
1

PriorityQueueの項目の優先度を増減したいとします。たとえば、長い画像リストをダウンロードしていて、30番目の画像を優先して優先したい場合があります。PriorityQueueは、すでにキュー内にある要素の並べ替えを許可しますか?

私が理解しているように、poll()は常に(コンパレータによって決定される)最も低い値のキューオブジェクトを返します。すでにキューに入っているアイテムの値を下げることができれば(例えば、この値がオブジェクトのintによって決定され、他の関数のintの値を減らした場合)、最初にpoll()によって返されるか、ソートされますpoll()は、挿入時にこれを行うことができます(たとえば、新しいキュー要素がリストの下に「自然な」深さに達するまでバブリングすることによって)?

これがPriorityBlockingQueueで行われた場合、同時性の問題が発生する可能性がありますか?

答えて

6

順序を決定するプロパティを変更すると、Javaのコレクションの中で要素の順序が自動的に変更されません。 .hashCode()、.equals()またはいくつかのコンパレータに依存するコレクションの場合、オブジェクトがコレクションにある間にオブジェクトを変更することはできません。これにより、ハッシュコード/等価または比較が異なる値を生成します。

PriorityQueue内で優先度を変更する場合は、オブジェクトを削除、変更、再挿入する必要があります。

2

あなたがソースコードを見れば、あなたはPriorityQueueにそれがresifts poll()たびに、それは常にはSIFT前上部にだったとアイテムを返します。

public class PQ { 

    int priority; 

    public PQ(int priority) { 
    this.priority = priority; 
    } 

    public static void main(String[] args) { 

    PQ one = new PQ(1); 
    PQ two = new PQ(2); 
    PQ three = new PQ(3); 
    PQ four = new PQ(4); 
    PQ five = new PQ(5); 

    PriorityQueue<PQ> q = new PriorityQueue<PQ>(3, new Comparator<PQ>() { 
     @Override 
     public int compare(PQ o1, PQ o2) { 
     return o1.priority-o2.priority; 
     } 
    }); 

    q.add(three); 
    q.add(one); 
    q.add(four); 
    q.add(two); 
    q.add(five); 

    //Prints; 
    //PQ-1 
    //PQ-2 
    //PQ-3 
    //PQ-4 
    //PQ-5 
    while (!q.isEmpty()) { 
     System.out.println(q.poll()); 
    } 

    q.add(three); 
    q.add(one); 
    q.add(four); 
    q.add(two); 
    q.add(five); 

    //Change the priority after it has been queued 
    four.priority = 10; 

    //Prints; 
    //PQ-1 
    //PQ-2 
    //PQ-3 
    //PQ-5 
    //PQ-10 
    while (!q.isEmpty()) { 
     System.out.println(q.poll()); 
    } 

    //Reset the priority 
    four.priority = 4; 

    q.add(three); 
    q.add(one); 
    q.add(four); 
    q.add(two); 
    q.add(five); 

    //Change the priority after it has been queued 
    four.priority = 0; 

    //Prints; 
    //PQ-1 
    //PQ-0 
    //PQ-2 
    //PQ-3 
    //PQ-5 
    while (!q.isEmpty()) { 
     System.out.println(q.poll()); 
    } 
    } 

    public String toString() { 
    return "PQ-" + priority; 
    } 

} 
+0

興味深い。私が望んでいたほど良いものではありませんでしたが、私が恐れていたよりも優れていました! –

0

あなたはプライオリティキューを反復した場合、あなたはそれはあなたが順序を変更したい場合は、私はあなたが別のプライオリティキューを作成示唆(最初の要素を除く)順不同にあるでしょう。

エントリの位置を変更したくない場合は、削除して、必要に応じてフィールドを変更してもう一度追加することをお勧めします。

+0

私は反復について話していません。私は 'PriorityQueue' **でイベントを順序付けするために使われた値を変更した後、それらのアイテムがキューに追加された後、' poll() 'によって取り出される順序を変更できるかどうかについて話しています。私はすでに 'PriorityQueue'を繰り返してStackOverflowの他の記事を読んでいます(どんな場合でも私がやりたいことではありませんでした)。 –

+1

値がキューの先頭にない場合には、これを行うことができます。 IMHOでは、Comparator、equals、およびhashCodeメソッドで最終フィールドのみを使用する必要があります。それ以外の場合は、問題を求めています。 –

+0

これはコンセンサスだと思われますが、これに感謝します。キューを静的にしたい場合、私は確かにファイナルを使用しますが、実際にキューを優先して優先順位を変更できるようにしたいと思います。それはこれを達成するための方法ではないかもしれませんが、ちょっと:) –

関連する問題