前言
最近通过一系列 Java 实战题目,梳理了不少基础知识点和容易踩坑的细节。本文会把这些内容体系化整理,涵盖字符串操作、数据结构、算法入门三大模块,每个模块都搭配「知识点解析 + 错题复盘」,适合 Java 新手查漏补缺,也能作为面试基础复习资料。
一、核心知识点体系梳理
(一)字符串操作(高频考点)
字符串是 Java 开发中最常用的类型,也是笔试面试的基础,以下是实战中必须掌握的核心知识点:
1. 字符串读取
- Scanner.nextLine() :读取整行输入(包含空格),适合处理带空格的字符串(如复合词、句子)。
- Scanner.next() :仅读取空格前的内容,适合处理无空格的字符串(如单个单词、数字字符串)。
- ❗ 关键注意:nextInt()/next() 后调用 nextLine() 会读取残留换行符,需额外调用 nextLine() 吸收。
2. 字符串内容操作
| 方法 | 作用 | 示例 |
|---|---|---|
| charAt(int index) | 获取指定索引的字符(索引从 0 开始) | "abc".charAt(0) → 'a' |
| substring(a, b) | 截取 [a, b) 区间的子串 | "hello".substring(1,3) → "el" |
| replace(c1, c2) | 替换所有指定字符 | "114514".replace('5', '') → "11414" |
| split("分隔符") | 按分隔符分割字符串为数组 | "I am Bob".split(" ") → ["I", "am", "Bob"] |
| toUpperCase() | 转大写(toLowerCase()转小写) | "am".toUpperCase() → "AM" |
| equals(str) | 比较字符串内容(区分大小写) | "Bob".equals("bob") → false |
| equalsIgnoreCase(str) | 忽略大小写比较内容 | "Bob".equalsIgnoreCase("bob") → true |
3. 高效字符串拼接
- StringBuilder:可变字符串,适合频繁拼接(如循环中拼接字符),核心方法:
-
- append(内容):追加字符 / 字符串(效率远高于 String + 拼接);
-
- reverse():反转字符串;
-
- toString():转为普通 String。
- 为什么不用 String 直接拼接?String 是不可变对象,每次拼接都会创建新对象,循环中使用效率极低。
(二)基础数据结构
1. 栈(Stack)
- 核心特性:先进后出(LIFO) ,类比「叠盘子」。
- 常用方法:push()(入栈)、pop()(出栈)、peek()(查看栈顶)、isEmpty()(判断空)。
- 应用场景:DFS(深度优先搜索)、括号匹配、逆序输出等。
2. 队列(Queue)
- 核心特性:先进先出(FIFO) ,类比「排队买票」。
- 常用方法:offer()(入队)、poll()(出队)、peek()(查看队首)、isEmpty()(判断空)。
- 应用场景:BFS(广度优先搜索)、任务调度、最短路径问题等。
(三)算法入门
1. DFS(深度优先搜索)
- 核心思想:一条路走到黑,走不通再回溯(类比「走迷宫选一条路走到头」)。
- 实现方式:递归(JVM 自动维护调用栈)或手动用栈。
- 关键步骤:选择当前节点 → 递归深入 → 回溯撤销选择。
- 适用场景:排列组合、树 / 图遍历、数独求解、N 皇后等。
2. BFS(广度优先搜索)
- 核心思想:层层扩散,先近后远(类比「往池塘扔石头,水波扩散」)。
- 实现方式:必须用队列(不能用栈)。
- 关键步骤:入队初始节点 → 出队当前节点 → 遍历邻接节点入队 → 重复直到队空。
- 适用场景:最短路径、层级遍历(如二叉树层序遍历)、找最近目标等。
3. 数学逻辑计算
- 字母循环偏移:(字符 - 'a' + n) % 26 + 'a'(小写字母向后错位 n 位,z 循环到 a)。
- 数位定位:通过数学计算确定目标位置所在的数字位数(如无限字符串第 n 位字符问题)。
二、高频错题复盘(避坑指南)
错题 1:输入读取残留换行符问题
错误代码
Scanner in = new Scanner(System.in);
int n = in.nextInt();
String s = in.nextLine(); // 错误:读取到的是n后的换行符,s为空
问题原因
nextInt() 仅读取整数,不会吸收输入后的换行符,后续 nextLine() 直接读取该换行符,导致字符串为空。
正确解法
在 nextInt() 后添加 in.nextLine() 吸收换行符:
int n = in.nextInt();
in.nextLine(); // 吸收残留换行符
String s = in.nextLine(); // 正确读取字符串
错题 2:字符串分割边界错误(千分位格式化 / 子串匹配)
错误代码(子串 "Bob" 匹配)
String s = "Bob";
for (int i = 0; i < 3; i++) { // 错误:循环边界少了等号
String sub = s.substring(i, i+3);
}
问题原因
当字符串 s 的长度为 3 时,若要遍历所有长度为 3 的子串,循环条件 i < len - 3 存在问题。因为当 i 取值到 len - 3 时,才是最后一个合法的子串起始位置,原条件 i < len - 3 会导致循环跳过最后一个子串的匹配。以 s = "Bob" 为例,len = 3,len - 3 = 0,此时 i < len - 3 不成立,循环直接结束,无法匹配到 "Bob" 这个子串 ;正确边界应包含 len - 3,即 i <= len - 3。
正确解法
String s = "Bob";
for (int i = 0; i <= 0; i++) { // 包含最后一个可能的起始位置
String sub = s.substring(i, i+3);
}
错题 3:用 == 比较字符串内容
错误代码
if (niuNiu == "elephant") { // 错误:比较的是内存地址,不是内容
// ...
}
问题原因
== 对于对象类型,比较的是内存地址(是否为同一个对象);而字符串内容比较必须用 equals()。
正确解法
if (niuNiu.equals("elephant")) { // 比较内容
// ...
}
// 避免空指针优化:常量放前面
if ("elephant".equals(niuNiu)) {
// ...
}
错题 4:字母循环偏移未处理边界(z→a)
错误代码
char now = (char)(origin + n); // 错误:z+1会变成'{',超出字母范围
问题原因
小写字母 ASCII 码范围是 97(a)-122(z),直接加 n 会超出范围,需用取模处理循环。
正确解法
int offset = (origin - 'a' + n) % 26; // 转为0-25后取模
char now = (char)('a' + offset); // 转回小写字母
错题 5:复合词简写时首字母转大写错误
错误代码
char upperChar = firstChar.toUpperCase(); // 错误:char不能直接调用String方法
问题原因
toUpperCase() 是 String 类的方法,char 类型不能直接调用,需先转为 String。
正确解法
String upperChar = String.valueOf(firstChar).toUpperCase();
三、实战题目总结(附核心思路)
| 题目类型 | 核心思路 |
|---|---|
| 字符替换(5→*) | 直接用 String.replace('5', '*') 高效替换 |
| 博弈游戏胜负判断 | 枚举胜负规则,用 equals() 比较棋子类型 |
| 千分位格式化 | 字符串从后往前遍历,每 3 位插入逗号,用 StringBuilder 拼接后反转 |
| 子串首次出现位置 | 遍历可能的起始位置,substring 截取后匹配(注意循环边界) |
| 字母向后错位加密 | 用 (char - 'a' + n) % 26 + 'a' 处理循环偏移 |
| 无限字符串第 n 位字符 | 先定位位数区间(1 位 / 2 位 / 3 位),再计算具体数字和字符位置 |
| 复合词简写 | 按空格分割字符串,提取每个单词首字母转大写,拼接结果 |
四、学习建议
- 基础优先:字符串操作、数据结构(栈 / 队列)是 Java 基础中的基础,必须熟练掌握,后续复杂算法都依赖这些知识点;
- 错题复盘:把踩过的坑(如换行符、== vs equals)整理成笔记,避免重复犯错;
- 实战驱动:通过简单题目巩固知识点(如本文中的实战题),再逐步过渡到复杂算法;
- 注重效率:字符串频繁拼接用 StringBuilder,避免不必要的性能损耗。
如果觉得本文对你有帮助,欢迎点赞、收藏~ 后续会持续更新 Java 进阶知识点和算法实战!