
本文详解如何通过 String.split(" ") 将文本拆分为单词数组,并利用 HashMap 统计每个单词出现次数,涵盖基础循环实现、merge() 优化写法及 Stream 函数式编程三种主流方案。
本文详解如何通过 `string.split(" ")` 将文本拆分为单词数组,并利用 `hashmap` 统计每个单词出现次数,涵盖基础循环实现、`merge()` 优化写法及 stream 函数式编程三种主流方案。
在 Java 中实现单词频次统计(即构建“单词 → 出现次数”的映射),是集合操作与字符串处理的经典练习。核心步骤包括:分词 → 遍历 → 累计计数。下面以清晰、可复用的方式逐步展开。
✅ 基础实现:显式判断 + 手动增减
最直观的方式是使用 HashMap<String, Integer>,先调用 split(" ") 得到单词数组,再遍历并根据单词是否已存在决定初始化为 1 或递增:
private static Map<String, Integer> countWords(String text) {
Map<String, Integer> wordMap = new HashMap<>();
String[] words = text.split(" ");
for (String word : words) {
if (wordMap.containsKey(word)) {
wordMap.put(word, wordMap.get(word) + 1);
} else {
wordMap.put(word, 1);
}
}
return wordMap;
}⚠️ 注意:此写法需确保 word 非空(如连续空格可能导致空字符串 "" 入 map)。实际项目中建议添加 word.trim().isEmpty() 过滤。
✅ 进阶优化:Map.merge() 一行替代分支逻辑
Java 8 引入的 merge(K, V, BiFunction) 方法可优雅合并键值:若键存在,则用给定函数(如 Integer::sum)合并旧值与新值;否则插入新键值对:
立即学习“Java免费学习笔记(深入)”;
private static Map<String, Integer> countWords(String text) {
Map<String, Integer> wordMap = new HashMap<>();
for (String word : text.split(" ")) {
wordMap.merge(word, 1, Integer::sum); // 等价于:put(key, getOrDefault(key, 0) + 1)
}
return wordMap;
}该写法线程安全(仅限单线程场景)、简洁且避免了重复查表(containsKey() + get()),性能更优。
✅ 函数式风格:Stream API 一行流式聚合
借助 Arrays.stream()、Collectors.groupingBy() 与 Collectors.summingInt(),可完全声明式地完成统计:
import java.util.*;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.*;
private static Map<String, Integer> countWords(String text) {
return Arrays.stream(text.split(" "))
.filter(word -> !word.trim().isEmpty()) // 过滤空字符串
.collect(groupingBy(Function.identity(), summingInt(w -> 1)));
}✅ 优势:无显式循环、高可读性、天然支持链式过滤/转换(如转小写统一计数:.map(String::toLowerCase))。
? 总结与建议
- 初学者:从基础 if-else 版本入手,理解 map 的增删查逻辑;
- 日常开发:优先使用 merge(),兼顾简洁性与性能;
- 复杂数据处理:选用 Stream 方案,便于后续扩展(如排序、限制 Top-N、多条件分组);
- 健壮性提示:生产环境应预处理输入——去除首尾空格、跳过空单词、考虑标点清洗(如 word.replaceAll("[^a-zA-Z]", ""))。
最终输出示例(输入 "Hello world Hello all"):
{Hello=2, world=1, all=1}


















