你好,我是林森lsjs
我的Github地址: sqyCoder (Qiyang) · GitHub


欢迎来到日耕一题,跟着我。今天这道题,表面是求和,实际上却在考你 Scanner 的"智能分词" 和 异常规避。
其实,Java 的 Scanner 早就给我们准备好了一套优雅的"跳过非整数"方案------hasNextInt()。
目录
[1. Scanner 的默认分词规则](#1. Scanner 的默认分词规则)
[2. hasNextInt() 与 nextInt() 的配合](#2. hasNextInt() 与 nextInt() 的配合)
[3. 为什么要用 hasNext() 外层循环](#3. 为什么要用 hasNext() 外层循环)
[三、分步代码编写 + 逐行讲解](#三、分步代码编写 + 逐行讲解)
[1. 第一步:创建 Scanner,初始化累加器](#1. 第一步:创建 Scanner,初始化累加器)
[2. 第二步:循环读取每个 token](#2. 第二步:循环读取每个 token)
[3. 第三步:输出结果并关闭](#3. 第三步:输出结果并关闭)
一、题目完整解读
原题
较为复杂情况下的求和
计算一个给定序列的整数和,序列中可能会混入无关的字母,求和的时候需要忽略。
输入格式
输入为一行,元素直接使用空格分割。
输出格式
输出为序列整数部分的和。
输入样例
1 2 3 a 4 5
输出样例
15
拆解所有要求
-
读一整行:元素用空格分割,这一点和上一题一样。
-
混合内容:整数里夹着字母(甚至可能夹着符号),但只看整数。
-
忽略无关字符:凡是不是整数的元素,统统当不存在。
-
输出仅为和:一个干净的数字,不能多任何汉字或冒号。
-
隐式坑位 :如果元素是
"123a"这种半数字半字母的,它算整数吗?题目没明说,但从样例看,只有纯整数的才算,沾一点字母都得跳过。
二、核心知识点
1. Scanner 的默认分词规则
Scanner 在调用 next()、nextInt()、hasNextInt() 等方法时,会 自动以空白字符(空格、换行、制表符)作为分隔符 ,把输入拆成一个一个的"词"(token)。
也就是说:
输入 "1 2 3 a 4 5" 会被自动切成:"1", "2", "3", "a", "4", "5"。
你不用自己调 split,Scanner 已经给你切好了。
即使输入是连续多个空格、换行混排,Scanner 也都能正确跳过,不会产生空字符串 ,天然避开了 split 的空字符串坑。
2. hasNextInt() 与 nextInt() 的配合
hasNextInt() 会检查 下一个 token 能否被解析成一个合法的 int 整数 (支持正负号),但它 不会消耗掉这个 token。
如果可以解析成整数,它就返回 true,然后你就可以放心地用 nextInt() 把这个数读出来累加。
如果不能解析(比如下一个 token 是 "a" 或 "123a"),就返回 false,你只需要用 next() 把它当作普通字符串读走并丢掉,循环继续。
这套组合拳,完美实现了"是整数就累加,不是整数就跳过"。
3. 为什么要用 hasNext() 外层循环
while (sc.hasNext()) 用来判断输入流里还有没有下一个 token。
只要没到文件末尾(EOF),循环就会一直跑,逐个处理每一个 token。
本地运行小提示:在 IDE 或命令行运行时,输入完样例后程序不会自动结束,你需要手动输入 EOF:
Windows:按
Ctrl + Z然后回车Mac / Linux:按
Ctrl + DOJ(在线判题系统)会把输入文件直接重定向给程序,会自动产生 EOF,你完全不用操心。
三、分步代码编写 + 逐行讲解
1. 第一步:创建 Scanner,初始化累加器
java
Scanner sc = new Scanner(System.in);
int sum = 0; // 初始值必须为 0
2. 第二步:循环读取每个 token
java
while (sc.hasNext()) { // 还有下一个 token 吗?
if (sc.hasNextInt()) { // 这个 token 是整数吗?
sum += sc.nextInt(); // 是整数,读出来累加
} else {
sc.next(); // 不是整数,读走并丢弃
}
}
为什么 else 里面不能什么都不写?
如果你只判断不读走,这个非整数 token 会永远卡在输入流里,
hasNext()一直为true,形成 死循环 。所以必须用next()把它"吃掉"。
3. 第三步:输出结果并关闭
java
System.out.println(sum);
sc.close();
输出只有一行数字,绝对不能加任何修饰词。
四、完整可运行代码
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// 1. 创建扫描器,连接标准输入
Scanner sc = new Scanner(System.in);
int sum = 0; // 累加和,初始化为 0
// 2. 循环读取每一个 token,直到 EOF
while (sc.hasNext()) {
// 2.1 如果下一个 token 可以解析成 int 整数
if (sc.hasNextInt()) {
sum += sc.nextInt(); // 读出整数并累加
} else {
// 2.2 否则就是一个非整数 token(字母、带字母的串等)
sc.next(); // 读出来扔掉,继续下一个
}
}
// 3. 输出最终的和
System.out.println(sum);
sc.close(); // 关闭资源,好习惯
}
}
五、执行流程全复盘(重点)

我们拿样例输入 "1 2 3 a 4 5",一步步跑一遍程序,让你看清楚每个变量的变化。
-
程序启动
sum = 0,Scanner 准备好读取输入。 -
第一次循环
sc.hasNext()→true(还有 token)sc.hasNextInt()→true(token 是"1",能转成整数)执行
sum += sc.nextInt()→ 读出1,sum = 1 -
第二次循环
hasNext()→truehasNextInt()→true(token"2")sum = 1 + 2 = 3 -
第三次循环
hasNextInt()→true(token"3")sum = 3 + 3 = 6 -
第四次循环
hasNextInt()→false(token"a")执行
sc.next()→ 读出"a"并丢弃,sum仍为6 -
第五次循环
hasNextInt()→true(token"4")sum = 6 + 4 = 10 -
第六次循环
hasNextInt()→true(token"5")sum = 10 + 5 = 15 -
第七次循环
hasNext()→false(EOF,没有更多 token 了)循环结束。
-
输出
15,程序退出。
六、总结
核心 :用 Scanner 的 hasNextInt() 自动切分 token 并判断------是整数就 nextInt() 累加,不是就用 next() 扔掉。
优势 :代码极短,无需手动 split,自动避开连续空格的坑,负数也天然支持。
注意 :非整数必须用 next() 拿走,否则死循环;
本地运行按 Ctrl + Z(Windows)或 Ctrl + D(Mac/Linux)结束输入。
一句话:利用 Scanner 的智能过滤,让只读整数求和变成最简单的循环。
++就到这里,诸位共勉!++
