如何存储Queue队列元素并重新添加,解决遍历后队空及NoSuchElementException报错
问题原因
- 你调用
Queue.remove()方法时会直接移除队列头部元素,处理后没有把元素放回队列,遍历一次后队列就为空,后续再调用remove()就会抛出NoSuchElementException - 循环逻辑存在语法错误:
do...while的判断条件写的是game = true,这是赋值操作不是等值判断,会导致循环永远不会按预期退出 - 外层for-each遍历队列的过程中修改队列结构(移除元素)本身就不符合集合遍历规范,会触发不可预期的行为
- 你把
Random实例创建写在循环内部,每次循环都重复创建实例,不仅性能差,还会影响随机数生成效果
修复方案
队列循环复用实现
不需要额外创建第二个队列,每次处理完取出的球员后,直接把他加回队列尾部即可实现循环遍历,修改后的代码如下:
// 初始获取球员队列 Queue<Baseball_PlayerItem> players = getplayers(); int ct = 0; int outCt = 0; boolean game = true; // 随机数实例只需要创建一次,放在循环外部 Random rand = new Random(); while (game) { // 先判断队列是否为空,避免报错 if (players.isEmpty()) { System.out.printf("\nAll done"); checkGameStatus(); game = false; break; } // 取出队首元素处理 Baseball_PlayerItem item = players.remove(); double rand2 = rand.nextDouble(); if (item.getBatAvg() > rand2) { System.out.printf("\nHit Perc: %s player: %s", rand2, item.getBatAvg()); ct++; if (ct >= 3) { System.out.printf("\nAnother home run total: %s", ct); } } else { System.out.printf("\nThats Miss"); outCt++; if (outCt == 3) { System.out.printf("\nThree outs game over :( Outs: %s",outCt); game = false; } } // 处理完的球员重新加回队列尾部,实现循环复用 players.add(item); }
游戏重启保留初始队列方案
如果需要每次重开游戏都重置为初始的球员顺序,可以在最开始就保存一份原始球员列表的副本,每次开新游戏直接用副本重建队列即可:
// 游戏初始化阶段保存原始球员列表 List<Baseball_PlayerItem> originPlayerList = new ArrayList<>(getplayers()); // 每次重开游戏时,直接用原始副本重建队列 Queue<Baseball_PlayerItem> players = new LinkedList<>(originPlayerList);
内容的提问来源于stack exchange,提问作者Raul
相关产品推荐
相关产品推荐

