字符串是编程中最常用的数据类型之一,Java 对字符串的处理提供了丰富而强大的支持。本文将深入解析 Java 字符串的特性、常用操作及最佳实践,帮助你掌握字符串处理的精髓。
字符串基础:Unicode 字符序列
从概念上讲,Java 字符串就是 Unicode 字符的序列。例如字符串 "Java\u2122" 由 5 个 Unicode 字符组成:J、a、v、a 和 ™(商标符号,Unicode 编码为 U+2122)。
在 Java 中,字符串通过 String 类实现,每个用双引号括起来的字符串都是 String 类的实例:
String empty = ""; // 空字符串
String greeting = "Hello"; // 包含5个字符的字符串
字符串的基本操作
子串提取:substring 方法
String 类的 substring 方法用于从一个字符串中提取子串,其签名如下:
String substring(int beginIndex, int endIndex)
beginIndex:子串的起始位置(包含)endIndex:子串的结束位置(不包含)
示例:
String greeting = "Hello";
String sub = greeting.substring(0, 3); // 结果为 "Hel"
技巧:子串的长度 = endIndex - beginIndex,这种设计让计算子串长度变得非常直观。
也可以只传入起始位置,获取从该位置到字符串末尾的子串:
String rest = greeting.substring(2); // 结果为 "llo"
字符串拼接
Java 中最常用的字符串操作之一就是拼接,使用 + 运算符即可:
String s1 = "Hello";
String s2 = "World";
String combined = s1 + " " + s2; // 结果为 "Hello World"
当 + 运算符两侧有一个是字符串类型时,另一个操作数会自动转换为字符串:
int age = 30;
String message = "Age: " + age; // 结果为 "Age: 30"
对于需要用特定分隔符拼接多个字符串的场景,可以使用 String.join 方法(Java 8+):
String[] parts = {"S", "M", "L", "XL"};
String sizes = String.join(" / ", parts); // 结果为 "S / M / L / XL"
不可变字符串:重要特性解析
Java 字符串有一个关键特性:不可变性。一旦创建了字符串对象,就不能修改其内容。例如,以下代码看似修改了字符串,实则创建了新字符串:
String greeting = "Hello";
greeting = greeting.substring(0, 3) + "p!"; // 现在 greeting 引用 "Help!"
不可变性的优缺点
优点:
- 字符串可以安全共享,节省内存
- 线程安全,无需考虑并发修改问题
- 可以作为哈希表的键,哈希值不会变化
缺点:
- 修改字符串会创建新对象,可能影响性能
- 大量字符串拼接操作效率较低
注意:不可变的是字符串对象本身,而不是引用变量。我们可以让字符串变量指向新的字符串对象。
字符串比较:equals 与 == 的区别
比较字符串是最容易出错的操作之一,关键要区分 equals 方法和 == 运算符:
equals方法:比较两个字符串的内容是否相同==运算符:比较两个字符串是否为同一个对象(即是否指向内存中的同一位置)
示例:
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
s1 == s2; // true(字符串常量池共享)
s1 == s3; // false(s3是新创建的对象)
s1.equals(s3); // true(内容相同)
警告:永远不要用
==运算符比较字符串内容,这是初学者最容易犯的错误之一!
其他比较方法:
equalsIgnoreCase:忽略大小写比较内容
"Hello".equalsIgnoreCase("HELLO"); // true
compareTo:按字典顺序比较,返回负数、零或正数
"apple".compareTo("banana"); // 负数("apple"在"banana"之前)
空串与 null 串:避免常见错误
处理字符串时,必须区分空串和 null 串:
-
空串:
""是长度为 0 的有效字符串对象
String empty = "";
empty.length(); // 0
empty.equals(""); // true
null 串:表示变量未引用任何字符串对象
String str = null;
str == null; // true
检查字符串是否有效(非 null 且非空):
String str = ...;
if (str != null && !str.isEmpty()) {
// 字符串有效,可安全操作
}
注意:在 null 上调用任何方法都会抛出
NullPointerException,所以必须先检查 null。
代码单元与码点:Unicode 处理
Java 字符串由 char 序列组成,char 采用 UTF-16 编码表示 Unicode 码点:
- 大部分常用字符用一个代码单元表示(16 位)
- 辅助字符(如 emoji 表情)需要两个代码单元表示
理解这一点对正确处理 Unicode 字符至关重要:
String s = "𝄞"; // 音乐符号,U+1D11E
s.length(); // 2(两个代码单元)
s.codePointCount(0, s.length()); // 1(实际码点数量)
常用方法:
codePointAt(int index):获取指定位置的码点offsetByCodePoints(int start, int codePointOffset):计算码点偏移后的索引codePoints():返回所有码点的流
遍历字符串的每个码点(正确处理辅助字符):
String s = "A𝄞B";
int[] codePoints = s.codePoints().toArray();
for (int cp : codePoints) {
System.out.println(Character.toChars(cp));
}
高效构建字符串:StringBuilder
由于字符串不可变,频繁拼接字符串会创建大量临时对象,影响性能。此时应该使用 StringBuilder:
// 低效方式
String result = "";
for (int i = 0; i < 1000; i++) {
result += i; // 每次都会创建新字符串
}
// 高效方式
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
builder.append(i); // 在原有对象上修改
}
String result = builder.toString();
tringBuilder 常用方法:
append(...):添加各种类型数据到末尾insert(int offset, ...):在指定位置插入数据delete(int start, int end):删除指定范围的字符setCharAt(int index, char c):修改指定位置的字符reverse():反转字符串toString():转换为 String 对象
提示:
StringBuffer是StringBuilder的线程安全版本,性能稍低,单线程环境下优先使用StringBuilder。
常用 String API 精选
String 类包含 50 多个方法,以下是最常用的一些:
-
获取信息
length():返回代码单元数量isEmpty():判断是否为空串charAt(int index):获取指定位置的代码单元
-
查找操作
indexOf(...):查找子串或码点首次出现的位置lastIndexOf(...):查找子串或码点最后出现的位置startsWith(String prefix):判断是否以指定前缀开头endsWith(String suffix):判断是否以指定后缀结尾
-
转换操作
toUpperCase():转换为大写toLowerCase():转换为小写trim():去除首尾空白字符(Java 11+ 推荐使用strip())replace(CharSequence old, CharSequence new):替换所有匹配的子串
-
其他常用方法
split(String regex):按正则表达式拆分字符串concat(String str):拼接字符串(类似+,但效率较低)matches(String regex):判断是否匹配正则表达式
示例:
String str = " Hello World ";
str.trim(); // "Hello World"
str.toUpperCase(); // " HELLO WORLD "
str.replace("World", "Java"); // " Hello Java "
str.startsWith("He"); // false(因为有前导空格)
学习资源:阅读 API 文档
String 类方法众多,不可能全部记住。学会查阅官方 API 文档是必备技能:
- 文档位置:JDK 安装目录下的
docs/api/index.html - 在线版本:Oracle Java 8 API 文档
- 查找方法:
- 在左侧找到
java.lang包 - 找到
String类 - 查看方法摘要和详细描述
- 在左侧找到
提示:将 API 文档添加到浏览器书签,养成随时查阅的习惯。
最佳实践总结
- 优先使用
equals方法比较字符串内容 - 处理可能为 null 的字符串时,先检查 null
- 频繁拼接字符串时使用
StringBuilder - 注意区分代码单元和码点,正确处理 Unicode 字符
- 避免创建不必要的字符串对象
- 字符串常量优先使用字面量形式(
"abc")而非new String("abc")
掌握 Java 字符串处理不仅能提高代码质量和效率,也是理解 Java 面向对象特性的重要一步。字符串的不可变性、常量池机制等设计思想,在 Java 其他部分也有广泛应用。多实践、多查阅文档,才能真正熟练掌握这些技能。

被折叠的 条评论
为什么被折叠?



