Java中如何使用forEach循环按优先级规则返回队列中的船舶实例
原有代码问题梳理
- 逻辑错误:现有循环仅判断队列第一个元素的匹配规则,若第一艘船不满足最高优先级规则,也会直接返回对应结果,不会向后查找队列中更高优先级的船舶
- 错误修改原队列:else分支调用
poll()会移除原队列的首个元素,违反peek方法不修改原队列的要求 - 字符串比较错误:使用
==判断船名,Java中字符串内容对比需使用equals()方法 - 空判断位置错误:空队列判断放在循环后,空队列时会先进入循环逻辑,存在异常风险
正确实现方案
实现逻辑:按优先级从高到低的顺序匹配船舶,队列遍历顺序本身就是入队顺序,第一个匹配对应优先级规则的就是最早入队的符合条件的船舶。如果所有高优先级规则都没有匹配项,直接返回队列首个元素即可。
版本1:按优先级分层遍历(逻辑直观易维护)
public Ship peek() { // 先处理空队列情况 if (ships.isEmpty()) { return null; } // 复制队列避免修改原队列,LinkedList遍历顺序就是入队顺序 Queue<Ship> shipCopy = new LinkedList<>(ships); // 优先级1:查找最早入队的BRAVO标识船舶 for (Ship s : shipCopy) { if (s.getFlag() == NauticalFlag.BRAVO) { return s; } } // 优先级2:查找最早入队的WHISKEY标识船舶 for (Ship s : shipCopy) { if (s.getFlag() == NauticalFlag.WHISKEY) { return s; } } // 优先级3:查找最早入队的HOTEL标识船舶 for (Ship s : shipCopy) { if (s.getFlag() == NauticalFlag.HOTEL) { return s; } } // 优先级4:查找最早入队的集装箱船,常量放前面避免getName()为空导致空指针 for (Ship s : shipCopy) { if ("ContainerShip".equals(s.getName())) { return s; } } // 所有高优先级都没匹配,返回最早入队的船舶 return shipCopy.peek(); }
版本2:单次遍历(队列较长时性能更优)
public Ship peek() { if (ships.isEmpty()) { return null; } Ship result = null; // 优先级数值越小优先级越高 int highestPriority = Integer.MAX_VALUE; for (Ship s : ships) { int currentPriority; if (s.getFlag() == NauticalFlag.BRAVO) { currentPriority = 1; } else if (s.getFlag() == NauticalFlag.WHISKEY) { currentPriority = 2; } else if (s.getFlag() == NauticalFlag.HOTEL) { currentPriority = 3; } else if ("ContainerShip".equals(s.getName())) { currentPriority = 4; } else { currentPriority = 5; } // 仅当找到更高优先级船舶时更新结果,保证同优先级下返回最早入队的船舶 if (currentPriority < highestPriority) { highestPriority = currentPriority; result = s; // 已经找到最高优先级的BRAVO,可直接提前退出遍历 if (highestPriority == 1) { break; } } } return result; }
内容的提问来源于stack exchange,提问作者HY2000
相关产品推荐
相关产品推荐

