2011-11-09 38 views
1

我想增加或降低PriorityQueue中的項目優先級:例如,我可能正在下載一長串圖像,並且突然想要第30個圖像具有最高優先級。PriorityQueue是否允許已經在隊列中的元素重新排序?

據我所知,poll()總是返回隊列對象的最低值(由比較器確定)。如果我可以降低隊列中某個項目的值(例如,如果該值由對象中的int確定,並且我在其他函數中減少了int值),那麼將首先返回poll(),還是排序這允許poll()在插入時完成這些操作(例如,通過在列表中向下滾動新隊列元素直到它們達到其「自然」深度)?

如果這是在PriorityBlockingQueue上完成的,它是否會導致併發問題?

回答

6

如果您更改確定其順序的屬性,則Java中的所有集合都不會自動重新排序元素。對於依賴於.hashCode(),.equals()或某個比較器的集合,您不允許在駐留在集合中時更改該對象,以便hashcode/equals或comparator會產生不同的值。

如果要在PriorityQueue內更改其優先級,您必須刪除,更改或重新插入對象。

2

如果你看看源代碼,每次你poll()PriorityQueue它resifts時間,但它總是返回該項目是在篩前頂部。

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()檢索的順序。我已經閱讀了StackOverflow上其他關於'PriorityQueue'迭代的文章(無論如何我都不想這麼做)。 –

+1

如果該值不在隊列的頂部,則可以使用它們。恕我直言,你應該只使用你的比較器中的final字段,equals和hashCode方法,否則你是在尋求麻煩。 –

+0

這似乎是共識,但感謝這一點 - 如果我希望隊列保持靜態,我當然會使用final,但實際上我希望隊列允許我隨意更改優先級。碰巧,這可能不是實現這一目標的方法,但嘿:) –

相關問題