Java对象列表遍历逻辑错误导致无法正确选择神明的问题求助
嘿,我看你在实现神明选择功能的时候遇到了挺头疼的逻辑bug——明明选了存在的神明ID,程序却错误地让你重新选,对吧?我来帮你拆解下问题根源,再给你一套可行的修正方案~
核心问题分析
你当前selectGodsForTeam方法里的内层for循环逻辑完全走偏了:每次只检查列表中当前索引j的神明ID,只要不匹配就直接跳进重试循环,根本没遍历完整个列表去确认这个ID到底存不存在。举个例子:用户第一次输入ID3,列表第一个元素是ID1,不匹配,程序立刻判定“神明不可用”让用户重新输入,但实际上列表里明明有ID3的神明,这就导致了完全没必要的错误提示。
另外还有个小隐患:当你从列表中remove元素后,列表长度会变化,如果后续循环还依赖原来的索引,可能会出现遍历遗漏,但这是次要问题,咱们先解决核心的逻辑错误。
修正后的代码实现
咱们把selectGodsForTeam方法的逻辑重新梳理一遍:每次用户输入ID后,先完整遍历整个列表确认是否存在该神明,找到就执行移动操作;没找到再提示用户重新输入,直到输入有效的ID。
修正后的代码如下:
void selectGodsForTeam(){ Scanner scanner = new Scanner(System.in); int chooseGodId; System.out.println("Please choose the 6 id's of the gods, you wish to pick:"); // 循环选6次神明 for(int i = 0; i < 6; i++){ boolean found = false; int targetIndex = -1; // 获取用户输入的ID chooseGodId = scanner.nextInt(); // 遍历整个列表查找匹配的神明 for(int j = 0; j < listOfAllGods.size(); j++){ if(chooseGodId == listOfAllGods.get(j).getId()){ found = true; targetIndex = j; break; // 找到就跳出遍历,节省资源 } } // 如果没找到,进入循环直到用户输入有效ID while(!found){ System.out.println("This god ID is not available, please pick another one:"); chooseGodId = scanner.nextInt(); // 再次遍历查找 for(int j = 0; j < listOfAllGods.size(); j++){ if(chooseGodId == listOfAllGods.get(j).getId()){ found = true; targetIndex = j; break; } } } // 执行移动操作:加入选中列表,从原列表移除 selectedGods.add(listOfAllGods.get(targetIndex)); listOfAllGods.remove(targetIndex); System.out.println("Successfully selected god with ID: " + chooseGodId); } scanner.close(); // 记得用完关闭Scanner,避免资源泄漏 }
逻辑说明
- 每次选择前,先初始化
found标记和targetIndex索引,用于记录是否找到匹配神明以及它在列表中的位置。 - 完整遍历
listOfAllGods查找用户输入的ID,找到后立刻跳出循环,避免不必要的遍历开销。 - 如果没找到,进入while循环,持续提示用户输入,直到找到有效的ID。
- 确认找到后再执行神明的移动操作,彻底避免“误判存在的ID为不可用”的情况。
额外优化建议
如果后续神明数量增多,遍历列表查找ID的效率会越来越低,你可以考虑在初始化的时候把神明存入HashMap<Integer, God>(键是ID,值是God对象),这样查找ID的时间复杂度会从O(n)降到O(1),效率提升明显。比如在Player的构造函数里初始化这个映射:
private Map<Integer, God> godMap; Player(List<God> listOfAllGods){ this.listOfAllGods = listOfAllGods; selectedGods = new ArrayList<>(); // 初始化ID到神明的映射 godMap = new HashMap<>(); for(God god : listOfAllGods){ godMap.put(god.getId(), god); } }
这样后续查找的时候就不用遍历列表,直接用godMap.containsKey(chooseGodId)判断是否存在,用godMap.get(chooseGodId)获取神明对象,不过要注意移除的时候要同时更新list和map哦~
另外,你还可以在用户选择前打印当前可选的神明列表,让用户清楚知道有哪些ID可以选,减少无效输入的概率~
备注:内容来源于stack exchange,提问作者OrlandoVSilva

