首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java PriorityBlockingQueue 遍歷陷阱:for 循環中 poll 導致只輸出一半數據

     編輯:程式設計綜合問答

問題現象

使用 `PriorityBlockingQueue` 存儲 10 個元素,遍歷輸出時卻只打印了 5 條記錄:

任務結束
[Event [id=1, priority=1], Event [id=2, priority=2], ...]
10
9
結果:Event [id=1, priority=1]
9
8
結果:Event [id=2, priority=2]
...
6
5
結果:Event [id=5, priority=5]

根本原因

問題出在這段遍歷代碼:

for (int i = 0; i < queue.size(); i++) {
    System.out.println(queue.size());
    Event poll = queue.poll(); // 每次 poll 移除一個元素,queue.size() 遞減
    System.out.println(queue.size());
    System.out.println("結果:" + poll);
}

邏輯缺陷:循環條件 `i < queue.size()` 中,`i` 遞增而 `queue.size()` 遞減。當移除 5 個元素後,`queue.size()` 變為 5,此時 `i` 也為 5,條件不再成立,循環提前結束。

正確解法

方案一:逆序循環

for (int i = queue.size() - 1; i >= 0; i--) {
    System.out.println(queue.size());
    Event poll = queue.poll();
    System.out.println(queue.size());
    System.out.println("結果:" + poll);
}

方案二:while 循環(推薦)

while (queue.size() > 0) {
    System.out.println(queue.size());
    Event poll = queue.poll();
    System.out.println(queue.size());
    System.out.println("結果:" + poll);
}

核心教訓

  • 避免在循環條件中使用動態變化的集合大小
  • 遍歷並修改集合時,優先用 Iterator、while 或先緩存大小
  • `poll()` 會移除並返回隊首元素,`peek()` 僅查看不移除

擴展:PriorityBlockingQueue 特性

該隊列按優先級排序(自然順序或 Comparator),而非 FIFO。示例中 `Event` 實現 `Comparable`,按 `priority` 升序排列,故輸出順序為 1→10。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved