
本文详解如何准确计算字符串中所有数字(连续数字视为整体)的奇偶分类和,纠正初学者常犯的字符ascii值误用、输入流错误等典型问题,并提供正则表达式与stream api两种专业实现方案。
本文详解如何准确计算字符串中所有数字(连续数字视为整体)的奇偶分类和,纠正初学者常犯的字符ascii值误用、输入流错误等典型问题,并提供正则表达式与stream api两种专业实现方案。
在处理字符串中的数字求和问题时,一个常见误区是将字符直接当作数值使用——例如 s.charAt(i) 返回的是 char 类型,其底层是 ASCII/Unicode 码点值(如 '0' 对应 48,'5' 对应 53),而非数字本身。原始代码中 Integer.parseInt(String.valueOf(temp)) 实际上是在尝试将 ASCII 值(如 83 对应 'S')转为整数并按奇偶累加,导致结果完全偏离预期。
更关键的是需求理解偏差:题目要求的是字符串中出现的数字(如 "abc25def" 中的 25)之和,而非单个数字字符('2' 和 '5')分别求和。二者语义截然不同:
- ✅ 正确解析:
"a12b34c"→ 提取12和34→ 偶数和 = 12 + 34 = 46 - ❌ 错误解析:
"a12b34c"→ 拆为'1','2','3','4'→ 偶数和 = 2 + 4 = 6
✅ 推荐方案一:使用正则提取连续数字(推荐用于真实业务场景)
import java.util.*;
import java.util.regex.*;
import java.util.stream.Collectors;
public class StringNumberSum {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); // ✅ 修正:从控制台读取,非字符串"System.in"
String s = sc.nextLine().trim();
Map<String, Integer> result = Pattern.compile("\d+")
.matcher(s)
.results()
.map(match -> Integer.parseInt(match.group()))
.collect(Collectors.groupingBy(
num -> num % 2 == 0 ? "Sum of Evens" : "Sum of Odds",
Collectors.reducing(0, Integer::sum)
));
System.out.println(result.getOrDefault("Sum of Evens", 0) + " "
+ result.getOrDefault("Sum of Odds", 0));
}
}说明:
\d+匹配一个或多个连续数字;.results()返回Stream<matchresult></matchresult>;match.group()获取匹配到的数字字符串(如"123"),再经Integer::parseInt转为整型参与逻辑判断与累加。
✅ 推荐方案二:仅对单个数字字符求和(适用于“数字字符”统计场景)
若实际需求是统计所有独立数字字符(即 '0'–'9')的奇偶和(如密码强度校验),可省略正则,直接遍历字符:
Map<String, Integer> digitSum = s.chars()
.filter(Character::isDigit)
.mapToObj(c -> c - '0') // ✅ 安全转为数字:'0'→0, '7'→7
.collect(Collectors.groupingBy(
d -> d % 2 == 0 ? "Sum of Evens" : "Sum of Odds",
Collectors.summingInt(Integer::intValue)
));⚠️ 注意:此处用
c - '0'替代Integer.parseInt(String.valueOf(c)),既高效又避免异常,是处理单数字字符的标准写法。
? 关键注意事项总结
-
输入源错误:
new Scanner("System.in")创建的是以字符串"System.in"为内容的扫描器,应改为new Scanner(System.in); -
字符 ≠ 数字:
char是编码值,需显式转换(c - '0'或Character.digit(c, 10)); -
连续数字识别:必须用正则
\d+或手动状态机解析,不可逐字符判断; -
空匹配防护:生产环境建议对
s做null/空白校验,并捕获NumberFormatException(尽管正则已保证纯数字); -
性能提示:对超长字符串,
Pattern.compile可提取为静态常量复用。
掌握这两种模式,即可精准应对「字符串内数字求和」类问题——区分「数值实体」与「字符符号」,是 Java 字符串处理的核心思维分水岭。

















