一、Java 字符串基础
在 Java 中,字符串是 不可变对象,即 String 一旦创建就不能修改。因此,字符串操作涉及大量的 性能优化。
Java 提供:
- String(不可变,适合少量字符串操作)
- StringBuilder(可变,适合频繁修改字符串)
- StringBuffer(线程安全版 StringBuilder)
二、String 类方法
1. 常见 String 操作
(1)字符串创建
String s1 = "hello"; // 直接赋值
String s2 = new String("hello"); // new 关键字创建(性能较低)
⚠️ 注意:
- s1 存储在字符串常量池,复用相同值的字符串。
- s2 存储在堆内存,不会复用。
(2)字符串比较
String s1 = "hello";
String s2 = new String("hello");
System.out.println(s1 == s2); // false(引用不同)
System.out.println(s1.equals(s2)); // true(内容相同)
⚠️ 易错点
- == 比较的是引用地址
- equals() 比较的是字符串内容
2. String 的常见方法
方法 | 作用 |
s.length() | 获取字符串长度 |
s.charAt(i) | 获取第 i 个字符 |
s.indexOf("a") | 查找 "a" 的位置 |
s.substring(a, b) | 截取 [a, b-1] |
s.replace("a", "b") | 替换 "a" 为 "b" |
s.toUpperCase() | 转大写 |
s.toLowerCase() | 转小写 |
s.trim() | 去除首尾空格 |
s.split(" ") | 按 " " 拆分字符串 |
3. 练习 1:字符串反转
题目描述
输入一个字符串,输出它的反转结果。
输入示例
hello
输出示例
olleh
Java 代码
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String s = scanner.next();String reversed = new StringBuilder(s).reverse().toString();System.out.println(reversed);}}
解析
- 使用 StringBuilder 的 reverse() 方法
- O(n) 复杂度
⚠️ 易错点
- 不要用 for + += 拼接字符串,性能低
- 应使用 StringBuilder 代替 String 直接拼接
三、StringBuilder(可变字符串)
适用于 频繁修改字符串 的场景,如 反转、拼接、插入、删除。
1. StringBuilder 方法
方法 | 作用 |
sb.append("abc") | 追加字符串 |
sb.insert(2, "x") | 在索引 2 处插入 "x" |
sb.replace(2, 4, "yy") | 替换 [2,4) 为 "yy" |
sb.delete(2, 4) | 删除 [2,4) |
sb.reverse() | 反转字符串 |
sb.toString() | 转换回 String |
2. 练习 2:统计字符出现次数
题目描述
输入一个字符串,统计其中每个字符出现的次数。
输入示例
aabbbcccc
输出示例
a:2
b:3
c:4
Java 代码
import java.util.HashMap;import java.util.Map;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String s = scanner.next();Map<Character, Integer> freqMap = new HashMap<>();for (char c : s.toCharArray()) {freqMap.put(c, freqMap.getOrDefault(c, 0) + 1);}for (Map.Entry<Character, Integer> entry : freqMap.entrySet()) {System.out.println(entry.getKey() + ":" + entry.getValue());}}}
解析
- 用 HashMap<Character, Integer> 记录字符出现次数
- 时间复杂度 O(n)
⚠️ 易错点
- 避免用 s.count(c) 遍历查找,效率低
- 要考虑大小写敏感问题(toLowerCase() 预处理)
3. 练习 3:判断回文串
题目描述
输入一个字符串,判断它是否是回文(即正着和反着读都一样)。
输入示例
abba
输出示例
YES
Java 代码
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String s = scanner.next();String reversed = new StringBuilder(s).reverse().toString();if (s.equals(reversed)) {System.out.println("YES");} else {System.out.println("NO");}}}
解析
- 利用 StringBuilder 反转,然后 用 equals() 比较
- 时间复杂度 O(n)
⚠️ 易错点
- 忽略大小写(toLowerCase() 预处理)
- 忽略空格(replace(" ", "") 预处理)
四、蓝桥杯字符串常考点
考点 | 典型题目 | 常见难点 |
字符串反转 | StringBuilder.reverse() | 不能用 += 拼接 |
统计字符次数 | HashMap 统计频率 | 避免 for 嵌套 |
判断回文 | 反转后比对 | 注意大小写 & 空格 |
字符串分割 | split() 解析 | 正则拆分复杂字符串 |
五、蓝桥杯字符串易错点
✅ 字符串比较
s1 == s2 // ❌ (比较地址)
s1.equals(s2) // ✅ (比较内容)
✅ 拼接字符串的效率问题
String s = "";
for (int i = 0; i < 10000; i++) {
s += "a"; // ❌ O(n^2)(慢)
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append("a"); // ✅ O(n)(快)
}
✅ 正则匹配 split() 问题
String s = "a b c";
String[] arr = s.split(" "); // ✅ ["a", "b", "c"]
⚠️ 但若 split("\\."),必须用双斜杠。
- 知识点总结
1. String 类与 StringBuilder 类的选择
- 当字符串不需要频繁修改时,使用 String 类,因为它的不可变性保证了线程安全,并且在一些场景下代码更简洁。
- 当需要频繁进行字符串拼接、插入、删除等操作时,使用 StringBuilder 类,它的性能明显优于 String 类。
2. 字符串操作技巧
- 可以使用 toCharArray() 方法将字符串转换为字符数组,方便进行字符级别的操作。
- 对于字符串的比较,使用 equals() 方法而不是 ==,因为 == 比较的是对象的引用,而 equals() 比较的是字符串的内容。
3. 性能优化
避免在循环中使用 String 的 + 运算符进行字符串拼接,因为每次拼接都会创建一个新的 String 对象,导致性能下降。应使用 StringBuilder 进行拼接。
蓝桥杯常考点
1. 字符串匹配与查找
- 考察 indexOf()、lastIndexOf() 等方法的使用,或者手动实现字符串匹配算法,如 KMP 算法。
- 可能要求在一个长字符串中查找多个子字符串的出现位置或次数。
2. 字符串分割与合并
- 使用 split() 方法将字符串按指定分隔符分割成字符串数组。
- 使用 StringBuilder 或 String 的 concat() 方法进行字符串合并。
3. 字符串转换与格式化
- 将其他数据类型转换为字符串,如 String.valueOf() 方法。
- 字符串的格式化输出,如使用 String.format() 方法。
- 高频操作与练习题
1. 字符串反转
方法1:StringBuilder的reverse()
public class StringReverse {public static String reverseString(String str) {return new StringBuilder(str).reverse().toString();}public static void main(String[] args) {String str = "Hello";String reversedStr = reverseString(str);System.out.println("反转后的字符串: " + reversedStr);}}
手动实现:
public class ManualStringReverse {public static String reverseString(String str) {char[] charArray = str.toCharArray();int left = 0, right = charArray.length - 1;while (left < right) {char temp = charArray[left];charArray[left] = charArray[right];charArray[right] = temp;left++;right--;}return new String(charArray);}public static void main(String[] args) {String str = "Hello";String reversedStr = reverseString(str);System.out.println("反转后的字符串: " + reversedStr);}}
判断回文串
public class PalindromeCheck {public static boolean isPalindrome(String str) {int left = 0, right = str.length() - 1;while (left < right) {if (str.charAt(left) != str.charAt(right)) {return false;}left++;right--;}return true;}public static void main(String[] args) {String str1 = "radar";String str2 = "hello";System.out.println(str1 + " 是否为回文串: " + isPalindrome(str1));System.out.println(str2 + " 是否为回文串: " + isPalindrome(str2));}}
正则表达式速查
常用正则:
数字:\\d
非数字:\\D
单词字符:\\w(等价于[a-zA-Z0-9_])
空白字符:\\s
String s = "a1b2c3";
String letters = s.replaceAll("\\d", ""); // "abc"
常考题型
字符串匹配:KMP算法(需掌握部分匹配表构建)。
子串问题:最长回文子串(动态规划或中心扩展法)。
字符串编码:处理Unicode字符(如中文字符统计)。