掌握Java字符串的核心概念和实用技巧
String是Java中最常用的类之一,用于表示字符序列。String类具有不可变性(immutable)的特征,这意味着一旦创建了String对象,就不能修改其内容。
// 使用字面量创建(推荐)
String str1 = "Hello World";
String str2 = "Hello World"; // 指向同一个对象
// 验证是否为同一对象
System.out.println(str1 == str2); // true
// 使用构造方法创建
String str3 = new String("Hello World");
String str4 = new String("Hello World");
// 每次都创建新对象
System.out.println(str3 == str4); // false
System.out.println(str3.equals(str4)); // true
// 从字符数组创建
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String str5 = new String(chars);
System.out.println(str5); // "Hello"
String text = "Hello World";
// 获取长度
int length = text.length(); // 11
// 判断是否为空
boolean isEmpty = text.isEmpty(); // false
boolean isBlank = text.isBlank(); // false (Java 11+)
// 安全的判空方法
if (text != null && !text.isEmpty()) {
System.out.println("字符串不为空");
}
String text = "Hello World";
// 查找字符或子字符串
int index1 = text.indexOf('o'); // 4
int index2 = text.lastIndexOf('o'); // 7
int index3 = text.indexOf("World"); // 6
// 字符串比较
boolean equals = text.equals("Hello World"); // true
boolean equalsIgnoreCase = text.equalsIgnoreCase("hello world"); // true
int compareResult = text.compareTo("Hello"); // 正数
// 包含判断
boolean contains = text.contains("World"); // true
boolean startsWith = text.startsWith("Hello"); // true
boolean endsWith = text.endsWith("World"); // true
String text = "Hello World";
// 字符串截取
String sub1 = text.substring(6); // "World"
String sub2 = text.substring(0, 5); // "Hello"
// 字符串替换
String replaced1 = text.replace('o', 'a'); // "Hella Warld"
String replaced2 = text.replace("World", "Java"); // "Hello Java"
String replaced3 = text.replaceAll("[aeiou]", "*"); // "H*ll* W*rld"
// 去除空白字符
String trimmed = " Hello World ".trim(); // "Hello World"
String stripped = " Hello World ".strip(); // "Hello World" (Java 11+)
String text = "Hello World";
// 大小写转换
String upper = text.toUpperCase(); // "HELLO WORLD"
String lower = text.toLowerCase(); // "hello world"
// 首字母大写(自定义方法)
public static String capitalize(String str) {
if (str == null || str.isEmpty()) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
}
// 字符串分割
String csv = "apple,banana,orange";
String[] fruits = csv.split(","); // ["apple", "banana", "orange"]
// 字符串连接
String joined = String.join(", ", fruits); // "apple, banana, orange"
// 使用StringBuilder进行高效连接
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString(); // "Hello World"
字符串池(String Pool)是JVM在堆内存中维护的一个特殊区域,用于存储字符串字面量,避免重复创建相同的字符串对象。
// 字面量会进入字符串池
String s1 = "Hello";
String s2 = "Hello";
System.out.println(s1 == s2); // true,指向同一个对象
// new创建的对象不在字符串池中
String s3 = new String("Hello");
System.out.println(s1 == s3); // false,不同对象
System.out.println(s1.equals(s3)); // true,内容相同
// intern()方法可以将字符串加入池中
String s4 = s3.intern();
System.out.println(s1 == s4); // true,现在指向池中的对象
当需要频繁修改字符串时,应该使用StringBuilder或StringBuffer,而不是String。
特性 | String | StringBuilder | StringBuffer |
---|---|---|---|
可变性 | 不可变 | 可变 | 可变 |
线程安全 | 安全 | 不安全 | 安全 |
性能 | 频繁修改时较慢 | 快 | 较快 |
使用场景 | 字符串不变 | 单线程频繁修改 | 多线程频繁修改 |
// 低效的字符串拼接(避免)
String result = "";
for (int i = 0; i < 1000; i++) {
result += "Hello "; // 每次都创建新对象
}
// 高效的字符串拼接(推荐)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append("Hello "); // 在原对象上修改
}
String result = sb.toString();
点击下面的链接,在在线IDE中实践String字符串的各种操作:
💡 在IDE中你可以运行示例代码,观察字符串的创建、操作和性能差异。
"Hello"
而不是 new String("Hello")
==
比较字符串内容// ✅ 好的做法
public class StringBestPractices {
// 安全的字符串比较
public static boolean safeEquals(String str1, String str2) {
return Objects.equals(str1, str2);
}
// 高效的字符串构建
public static String buildMessage(String[] parts) {
if (parts == null || parts.length == 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (String part : parts) {
if (part != null && !part.isEmpty()) {
sb.append(part).append(" ");
}
}
return sb.toString().trim();
}
// 格式化字符串
public static String formatUserInfo(String name, int age) {
return String.format("用户:%s,年龄:%d岁", name, age);
}
}
A: String的不可变性带来了多个好处:
A: 在以下情况下应该使用StringBuilder:
A: intern()方法的作用: