将字符后的整数存入ArrayList并放入Map的行尾读取代码问题
看起来你在处理这份结构化数据时,卡在了整数列表的读取逻辑上——你的循环判断条件和读取方式都有问题,我来帮你拆解一下:
1. while(scan.next() != "\n") 完全不符合Scanner的工作逻辑
Scanner的next()方法是按空白分隔符(空格、换行、制表符等)读取下一个token,它会自动跳过这些分隔符,永远不会返回"\n"这个字符串。所以这个条件永远是true,要么导致死循环,要么当没有更多token时直接抛出NoSuchElementException,程序直接崩掉。
2. 先scan.next()再scan.nextInt()会丢失数据
举个例子,处理J 2 1 3时,第一次循环里scan.next()会读取"2",但你没把它加入indexes,反而调用scan.nextInt()去读下一个数1——这样你直接丢了2这个数据,后续所有读取都会错位,逻辑彻底乱了。
正确的处理思路和代码
根据你的数据格式(数字 字符 整数列表 数字 字符 整数列表...),我们需要:
- 遍历所有token,跳过前面的数字;
- 把字符作为map的key;
- 持续读取后面的整数,直到遇到下一个非整数(也就是下一个字符)或者文件结束。
方案一:用Scanner的hasNextInt()判断,配合提前检查
// 假设你已经读取到当前的字符name(比如J) ArrayList<Integer> indexes = new ArrayList<>(); // 只要还有下一个整数,就继续读取 while (scan.hasNextInt()) { indexes.add(scan.nextInt()); // 提前检查下一个token是不是非整数(也就是下一个字符),是的话就停止 if (scan.hasNext() && !scan.hasNextInt()) { break; } } myMap.put(name, indexes);
方案二:先把所有token读入列表,再遍历处理(更直观,容易调试)
这种方式适合复杂的结构化数据,能更清晰地控制遍历流程:
List<String> allTokens = new ArrayList<>(); // 先把所有token读入列表 while (scan.hasNext()) { allTokens.add(scan.next()); } int currentIndex = 0; while (currentIndex < allTokens.size()) { // 跳过前面的数字(比如300、900这些) currentIndex++; // 读取当前字符作为map的key String key = allTokens.get(currentIndex); currentIndex++; ArrayList<Integer> indexes = new ArrayList<>(); // 读取后面的所有整数,直到遇到非整数或者列表结束 while (currentIndex < allTokens.size()) { try { int num = Integer.parseInt(allTokens.get(currentIndex)); indexes.add(num); currentIndex++; } catch (NumberFormatException e) { // 遇到非整数,跳出循环处理下一个字符 break; } } myMap.put(key, indexes); }
额外注意点
- 永远在调用
next()/nextInt()之前用hasNext()/hasNextInt()判断,避免抛出NoSuchElementException; - 如果你的数据格式有变动(比如字符前面的数字其实是key的一部分),可以调整遍历逻辑,但核心思路都是先区分字符和整数,再批量收集整数列表。
内容的提问来源于stack exchange,提问作者Boxify
相关产品推荐
相关产品推荐

