Java字符串处理详解,String、StringBuffer、StringBuilder
1. CharSequence接口概述
接口定义
CharSequence接口是char值的一个可读序列,是Java字符串处理的顶层接口。
实现类
Java中主要有三个类实现了CharSequence接口:
| 实现类 |
特点 |
用途 |
String |
不可变字符串 |
一般字符串操作 |
StringBuffer |
可变字符串,线程安全 |
多线程环境下的字符串构建 |
StringBuilder |
可变字符串,线程不安全 |
单线程环境下的字符串构建 |
共同特征
- 都被
final修饰符修饰,无法被继承
- 无法重写方法
- 都提供了字符序列的基本操作方法
2. String类详解
2.1 String类特点
String类是描述字符串的类,具有以下特征:
- 实现接口 :
Serializable、CharSequence、Comparable接口
- 不可变性:String对象是常量,一旦被初始化不能改变
- 线程安全:由于不可变性,天然线程安全
- 内存优化:使用字符串常量池进行内存管理
2.2 String构造方法
java
复制代码
// 1. 空字符串构造
String str1 = new String(); // 相当于 ""
// 2. 从另一个String构造(克隆)
String original = "Hello";
String str2 = new String(original); // 创建original的副本对象
// 3. 从字节数组构造
byte[] bytes = {72, 101, 108, 108, 111}; // "Hello"的ASCII码
String str3 = new String(bytes); // 使用系统默认编码转换
// 4. 从字符数组构造
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String str4 = new String(chars); // 将字符数组转换成字符串
// 5. 直接赋值(推荐)
String str5 = "Hello"; // 最常用的方式
2.3 String常用方法
获取类方法
| 方法名 |
功能描述 |
示例 |
charAt(int index) |
获取指定位置上的字符 |
"Hello".charAt(1) → 'e' |
codePointAt(int index) |
获取指定位置字符的ASCII码 |
"A".codePointAt(0) → 65 |
length() |
获取字符串长度 |
"Hello".length() → 5 |
indexOf(String str) |
获取子串首次出现位置 |
"Hello".indexOf("ll") → 2 |
lastIndexOf(String str) |
反向获取子串位置 |
"Hello".lastIndexOf("l") → 3 |
substring(int beginIndex) |
获取从指定位置开始的子串 |
"Hello".substring(1) → "ello" |
substring(int begin, int end) |
获取指定范围的子串 |
"Hello".substring(1,4) → "ell" |
java
复制代码
// 获取方法示例
public class StringGetDemo {
public static void main(String[] args) {
String str = "Hello World";
System.out.println("字符串长度: " + str.length()); // 11
System.out.println("第5个字符: " + str.charAt(4)); // 'o'
System.out.println("'o'的位置: " + str.indexOf('o')); // 4
System.out.println("'l'最后位置: " + str.lastIndexOf('l')); // 9
System.out.println("子串: " + str.substring(6)); // "World"
System.out.println("子串: " + str.substring(0, 5)); // "Hello"
// indexOf也可以判断是否包含某字符或字符串
if (str.indexOf("World") != -1) {
System.out.println("字符串包含'World'");
}
}
}
判断类方法
| 方法名 |
功能描述 |
示例 |
matches(String regex) |
判断是否匹配正则表达式 |
"123".matches("\\d+") → true |
endsWith(String suffix) |
判断是否以指定字符串结尾 |
"Hello.java".endsWith(".java") → true |
startsWith(String prefix) |
判断是否以指定字符串开头 |
"Hello".startsWith("He") → true |
isEmpty() |
是否为空(JDK 1.6后) |
"".isEmpty() → true |
contains(CharSequence s) |
是否包含指定字符序列 |
"Hello".contains("ell") → true |
equals(Object obj) |
判断字符串内容是否相同 |
"Hello".equals("Hello") → true |
equalsIgnoreCase(String str) |
忽略大小写判断内容是否相同 |
"Hello".equalsIgnoreCase("hello") → true |
compareTo(String str) |
按字典顺序比较字符串 |
"abc".compareTo("abd") → -1 |
java
复制代码
// 判断方法示例
public class StringJudgeDemo {
public static void main(String[] args) {
String str1 = "Hello World";
String str2 = "HELLO WORLD";
String email = "user@example.com";
String phone = "13812345678";
// 基本判断
System.out.println("是否为空: " + str1.isEmpty()); // false
System.out.println("包含'World': " + str1.contains("World")); // true
System.out.println("以'Hello'开头: " + str1.startsWith("Hello")); // true
System.out.println("以'.com'结尾: " + email.endsWith(".com")); // true
// 相等性判断
System.out.println("内容相等: " + str1.equals(str2)); // false
System.out.println("忽略大小写相等: " + str1.equalsIgnoreCase(str2)); // true
// 字典顺序比较
System.out.println("字典顺序比较: " + "abc".compareTo("abd")); // -1
// 正则表达式匹配
System.out.println("是否为手机号: " + phone.matches("1[3-9]\\d{9}")); // true
}
}
转换类方法
| 方法名 |
功能描述 |
示例 |
toCharArray() |
转换为字符数组 |
"Hello".toCharArray() → ['H','e','l','l','o'] |
getBytes() |
转换为字节数组 |
"Hello".getBytes() |
toUpperCase() |
转换为大写 |
"hello".toUpperCase() → "HELLO" |
toLowerCase() |
转换为小写 |
"HELLO".toLowerCase() → "hello" |
copyValueOf(char[] data) |
静态方法,字符数组转字符串 |
String.copyValueOf(chars) |
valueOf(基本类型) |
静态方法,基本类型转字符串 |
String.valueOf(123) → "123" |
java
复制代码
// 转换方法示例
public class StringConvertDemo {
public static void main(String[] args) {
String str = "Hello World";
// 转换为字符数组
char[] chars = str.toCharArray();
System.out.println("字符数组: " + Arrays.toString(chars));
// 转换为字节数组
byte[] bytes = str.getBytes();
System.out.println("字节数组: " + Arrays.toString(bytes));
// 大小写转换
System.out.println("大写: " + str.toUpperCase()); // "HELLO WORLD"
System.out.println("小写: " + str.toLowerCase()); // "hello world"
// 静态方法:基本类型转字符串
String intStr = String.valueOf(123);
String doubleStr = String.valueOf(3.14);
String boolStr = String.valueOf(true);
System.out.println("整数转字符串: " + intStr); // "123"
System.out.println("小数转字符串: " + doubleStr); // "3.14"
System.out.println("布尔转字符串: " + boolStr); // "true"
// 字符数组转字符串
char[] charArray = {'J', 'a', 'v', 'a'};
String fromChars = String.copyValueOf(charArray);
System.out.println("字符数组转字符串: " + fromChars); // "Java"
}
}
替换类方法
| 方法名 |
功能描述 |
示例 |
replace(char oldChar, char newChar) |
替换所有指定字符 |
"Hello".replace('l', 'x') → "Hexxo" |
replace(CharSequence target, CharSequence replacement) |
替换所有指定字符串 |
"Hello World".replace("World", "Java") |
replaceAll(String regex, String replacement) |
用正则表达式替换 |
"abc123def".replaceAll("\\d+", "XXX") |
replaceFirst(String regex, String replacement) |
替换第一个匹配项 |
"abc123def456".replaceFirst("\\d+", "XXX") |
java
复制代码
// 替换方法示例
public class StringReplaceDemo {
public static void main(String[] args) {
String str = "Hello World, Hello Java";
// 字符替换
System.out.println("替换字符'l': " + str.replace('l', 'x'));
// 输出: "Hexxo Worxd, Hexxo Java"
// 字符串替换
System.out.println("替换'Hello': " + str.replace("Hello", "Hi"));
// 输出: "Hi World, Hi Java"
// 正则表达式替换所有
String text = "电话:138-1234-5678,手机:139-8765-4321";
System.out.println("隐藏手机号: " + text.replaceAll("1[3-9]\\d-\\d{4}-\\d{4}", "***-****-****"));
// 只替换第一个匹配项
System.out.println("替换第一个'Hello': " + str.replaceFirst("Hello", "Hi"));
// 输出: "Hi World, Hello Java"
}
}
切割类方法
| 方法名 |
功能描述 |
示例 |
split(String regex) |
按正则表达式切割字符串 |
"a,b,c".split(",") → ["a","b","c"] |
split(String regex, int limit) |
限制切割次数 |
"a,b,c,d".split(",", 2) → ["a","b,c,d"] |
java
复制代码
// 切割方法示例
public class StringSplitDemo {
public static void main(String[] args) {
String str = "apple,banana,orange,grape";
String path = "C:\\Program Files\\Java\\bin";
String text = "Java is very good";
// 基本切割
String[] fruits = str.split(",");
System.out.println("水果数组: " + Arrays.toString(fruits));
// 输出: [apple, banana, orange, grape]
// 按反斜杠切割(需要转义)
String[] pathParts = path.split("\\\\");
System.out.println("路径分割: " + Arrays.toString(pathParts));
// 输出: [C:, Program Files, Java, bin]
// 按正则表达式切割(多个空格)
String[] words = text.split("\\s+");
System.out.println("单词数组: " + Arrays.toString(words));
// 输出: [Java, is, very, good]
// 限制切割次数
String[] limitedSplit = str.split(",", 2);
System.out.println("限制切割: " + Arrays.toString(limitedSplit));
// 输出: [apple, banana,orange,grape]
}
}
去除类方法
| 方法名 |
功能描述 |
示例 |
trim() |
去除两端空格 |
" Hello ".trim() → "Hello" |
strip() |
去除两端空白字符(JDK 11+) |
" Hello ".strip() → "Hello" |
stripLeading() |
去除开头空白字符(JDK 11+) |
" Hello ".stripLeading() → "Hello " |
stripTrailing() |
去除结尾空白字符(JDK 11+) |
" Hello ".stripTrailing() → " Hello" |
java
复制代码
// 去除方法示例
public class StringTrimDemo {
public static void main(String[] args) {
String str = " Hello World ";
String str2 = "\t\n Java Programming \r\n";
System.out.println("原字符串: '" + str + "'");
System.out.println("去除空格: '" + str.trim() + "'");
System.out.println("原字符串: '" + str2 + "'");
System.out.println("去除空格: '" + str2.trim() + "'");
// 实际应用:处理用户输入
String userInput = " user@example.com ";
String cleanInput = userInput.trim();
System.out.println("清理后的输入: '" + cleanInput + "'");
}
}
3. StringBuffer类详解
3.1 StringBuffer特点
- 可变长度:可以对字符串内容进行修改、增加和删除
- 线程安全:方法被synchronized修饰,适用于多线程环境
- 缓冲容器:内部使用字符数组作为缓冲区
- 最终转换 :通过
toString()方法返回String对象
3.2 StringBuffer构造方法
java
复制代码
// 1. 默认构造方法,初始容量为16
StringBuffer sb1 = new StringBuffer();
// 2. 指定初始容量
StringBuffer sb2 = new StringBuffer(50);
// 3. 用字符串初始化
StringBuffer sb3 = new StringBuffer("Hello");
3.3 StringBuffer特有方法
修改类方法
| 方法名 |
功能描述 |
示例 |
append(各种类型) |
将数据添加到结尾 |
sb.append("World") |
insert(int offset, 各种类型) |
在指定位置插入数据 |
sb.insert(5, " Java") |
delete(int start, int end) |
删除指定范围内容 |
sb.delete(0, 5) |
deleteCharAt(int index) |
删除指定位置字符 |
sb.deleteCharAt(0) |
reverse() |
反转字符串 |
sb.reverse() |
replace(int start, int end, String str) |
替换指定范围内容 |
sb.replace(0, 5, "Hi") |
setCharAt(int index, char ch) |
替换指定位置字符 |
sb.setCharAt(0, 'H') |
java
复制代码
// StringBuffer修改方法示例
public class StringBufferDemo {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello");
System.out.println("初始值: " + sb); // Hello
// append - 追加内容
sb.append(" World");
System.out.println("追加后: " + sb); // Hello World
sb.append(123).append(true).append(3.14);
System.out.println("链式追加: " + sb); // Hello World123true3.14
// insert - 插入内容
sb = new StringBuffer("Hello World");
sb.insert(6, "Java ");
System.out.println("插入后: " + sb); // Hello Java World
// delete - 删除内容
sb.delete(6, 11); // 删除"Java "
System.out.println("删除后: " + sb); // Hello World
// deleteCharAt - 删除单个字符
sb.deleteCharAt(5); // 删除空格
System.out.println("删除字符后: " + sb); // HelloWorld
// replace - 替换内容
sb.replace(0, 5, "Hi");
System.out.println("替换后: " + sb); // HiWorld
// reverse - 反转
sb.reverse();
System.out.println("反转后: " + sb); // dlroWiH
// setCharAt - 设置指定位置字符
sb.setCharAt(0, 'D');
System.out.println("设置字符后: " + sb); // DlroWiH
}
}
获取类方法(与String类似)
| 方法名 |
功能描述 |
charAt(int index) |
获取指定位置字符 |
indexOf(String str) |
获取子串位置 |
lastIndexOf(String str) |
反向获取子串位置 |
length() |
获取长度 |
substring(int start) |
获取子串 |
substring(int start, int end) |
获取指定范围子串 |
toString() |
转换为String对象 |
3.4 StringBuffer其他实用方法
java
复制代码
// StringBuffer其他方法示例
public class StringBufferAdvancedDemo {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World");
// 获取字符数组
char[] chars = new char[5];
sb.getChars(0, 5, chars, 0); // 从sb的0-5位置复制到chars数组
System.out.println("字符数组: " + Arrays.toString(chars)); // [H, e, l, l, o]
// 容量相关
System.out.println("当前长度: " + sb.length()); // 11
System.out.println("当前容量: " + sb.capacity()); // 27 (初始16 + 扩展)
// 确保容量
sb.ensureCapacity(50);
System.out.println("确保容量后: " + sb.capacity()); // 54
// 设置长度
sb.setLength(5);
System.out.println("设置长度后: " + sb); // Hello
}
}
4. StringBuilder类详解
4.1 StringBuilder特点
- JDK 1.5后出现:作为StringBuffer的简易替换
- 功能相同:与StringBuffer提供相同的API
- 线程不安全:没有同步控制,性能更好
- 单线程推荐:在单线程环境下推荐使用
4.2 StringBuilder使用示例
java
复制代码
// StringBuilder使用示例
public class StringBuilderDemo {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Hello");
// 所有StringBuffer的方法StringBuilder都有
sb.append(" World")
.append(" Java")
.append(" Programming");
System.out.println("构建结果: " + sb.toString());
// 性能测试对比
performanceTest();
}
// 性能测试
public static void performanceTest() {
int times = 10000;
// String拼接测试
long start = System.currentTimeMillis();
String str = "";
for (int i = 0; i < times; i++) {
str += "a";
}
long stringTime = System.currentTimeMillis() - start;
// StringBuilder拼接测试
start = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < times; i++) {
sb.append("a");
}
String sbResult = sb.toString();
long sbTime = System.currentTimeMillis() - start;
// StringBuffer拼接测试
start = System.currentTimeMillis();
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < times; i++) {
sbf.append("a");
}
String sbfResult = sbf.toString();
long sbfTime = System.currentTimeMillis() - start;
System.out.println("String拼接时间: " + stringTime + "ms");
System.out.println("StringBuilder拼接时间: " + sbTime + "ms");
System.out.println("StringBuffer拼接时间: " + sbfTime + "ms");
}
}
5. 三种字符串类的对比
5.1 特性对比表
| 特性 |
String |
StringBuffer |
StringBuilder |
| 可变性 |
不可变 |
可变 |
可变 |
| 线程安全 |
安全(不可变) |
安全(同步) |
不安全 |
| 性能 |
低(频繁创建对象) |
中等 |
高 |
| 内存使用 |
高(创建多个对象) |
低 |
低 |
| 适用场景 |
少量字符串操作 |
多线程环境 |
单线程环境 |
| JDK版本 |
1.0+ |
1.0+ |
1.5+ |
5.2 使用场景选择
java
复制代码
// 使用场景示例
public class StringChoiceDemo {
public static void main(String[] args) {
// 场景1:字符串不变,少量操作 - 使用String
String greeting = "Hello";
String message = greeting + " World!"; // 适合用String
// 场景2:单线程环境,大量字符串拼接 - 使用StringBuilder
StringBuilder htmlBuilder = new StringBuilder();
htmlBuilder.append("<html>")
.append("<head><title>页面标题</title></head>")
.append("<body>")
.append("<h1>欢迎</h1>")
.append("</body>")
.append("</html>");
String html = htmlBuilder.toString();
// 场景3:多线程环境,需要字符串拼接 - 使用StringBuffer
StringBuffer logBuffer = new StringBuffer();
// 多个线程可能同时操作logBuffer
synchronized(logBuffer) {
logBuffer.append("[INFO] ")
.append(new Date())
.append(" - 应用启动成功");
}
// 场景4:格式化字符串 - 使用String.format
String formatted = String.format("用户%s,年龄%d,余额%.2f", "张三", 25, 1000.5);
System.out.println(formatted);
}
}
5.3 性能对比测试
java
复制代码
// 性能对比完整测试
public class StringPerformanceTest {
private static final int ITERATIONS = 50000;
public static void main(String[] args) {
testStringConcat();
testStringBuilder();
testStringBuffer();
}
// 测试String拼接
public static void testStringConcat() {
long start = System.currentTimeMillis();
String result = "";
for (int i = 0; i < ITERATIONS; i++) {
result += "a";
}
long end = System.currentTimeMillis();
System.out.println("String拼接 " + ITERATIONS + " 次耗时: " + (end - start) + "ms");
}
// 测试StringBuilder
public static void testStringBuilder() {
long start = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ITERATIONS; i++) {
sb.append("a");
}
String result = sb.toString();
long end = System.currentTimeMillis();
System.out.println("StringBuilder拼接 " + ITERATIONS + " 次耗时: " + (end - start) + "ms");
}
// 测试StringBuffer
public static void testStringBuffer() {
long start = System.currentTimeMillis();
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < ITERATIONS; i++) {
sbf.append("a");
}
String result = sbf.toString();
long end = System.currentTimeMillis();
System.out.println("StringBuffer拼接 " + ITERATIONS + " 次耗时: " + (end - start) + "ms");
}
}
6. 字符串处理最佳实践
6.1 选择原则
- 字符串不变或少量操作 → 使用
String
- 单线程大量拼接 → 使用
StringBuilder
- 多线程大量拼接 → 使用
StringBuffer
- 格式化字符串 → 使用
String.format() 或 MessageFormat
6.2 常见陷阱和解决方案
java
复制代码
// 字符串处理陷阱示例
public class StringTrapDemo {
public static void main(String[] args) {
// 陷阱1:字符串比较使用==而不是equals
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println("== 比较: " + (str1 == str2)); // false
System.out.println("equals比较: " + str1.equals(str2)); // true
// 陷阱2:空字符串判断
String nullStr = null;
String emptyStr = "";
// 错误方式
// System.out.println(nullStr.isEmpty()); // NullPointerException
// 正确方式
System.out.println("null判断: " + (nullStr == null || nullStr.isEmpty()));
System.out.println("空串判断: " + (emptyStr == null || emptyStr.isEmpty()));
// 更好的方式(JDK 8+)
System.out.println("使用工具类: " + isBlank(nullStr));
System.out.println("使用工具类: " + isBlank(emptyStr));
System.out.println("使用工具类: " + isBlank(" "));
// 陷阱3:循环中的字符串拼接
// 错误方式(性能差)
badStringConcat();
// 正确方式(性能好)
goodStringConcat();
// 陷阱4:split方法的特殊字符
String path = "C:\\Users\\Documents\\file.txt";
// 错误方式
// String[] parts = path.split("\\"); // 异常
// 正确方式
String[] parts = path.split("\\\\"); // 需要双重转义
System.out.println("路径分割: " + Arrays.toString(parts));
}
// 判断字符串是否为空或只包含空白字符
public static boolean isBlank(String str) {
return str == null || str.trim().isEmpty();
}
// 错误的字符串拼接方式
public static void badStringConcat() {
long start = System.currentTimeMillis();
String result = "";
for (int i = 0; i < 1000; i++) {
result += "第" + i + "次拼接;";
}
long end = System.currentTimeMillis();
System.out.println("错误拼接耗时: " + (end - start) + "ms");
}
// 正确的字符串拼接方式
public static void goodStringConcat() {
long start = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append("第").append(i).append("次拼接;");
}
String result = sb.toString();
long end = System.currentTimeMillis();
System.out.println("正确拼接耗时: " + (end - start) + "ms");
}
}
6.3 实用工具方法
java
复制代码
// 字符串处理工具类
public class StringUtils {
// 判断字符串是否为空或null
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
// 判断字符串是否为空、null或只包含空白字符
public static boolean isBlank(String str) {
return str == null || str.trim().length() == 0;
}
// 安全的字符串截取
public static String safeSubstring(String str, int start, int end) {
if (isEmpty(str)) {
return "";
}
if (start < 0) start = 0;
if (end > str.length()) end = str.length();
if (start >= end) return "";
return str.substring(start, end);
}
// 重复字符串
public static String repeat(String str, int count) {
if (isEmpty(str) || count <= 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append(str);
}
return sb.toString();
}
// 首字母大写
public static String capitalize(String str) {
if (isEmpty(str)) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
}
// 驼峰命名转下划线
public static String camelToUnderscore(String camelCase) {
if (isEmpty(camelCase)) {
return camelCase;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < camelCase.length(); i++) {
char c = camelCase.charAt(i);
if (Character.isUpperCase(c) && i > 0) {
sb.append('_');
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
// 下划线转驼峰命名
public static String underscoreToCamel(String underscore) {
if (isEmpty(underscore)) {
return underscore;
}
StringBuilder sb = new StringBuilder();
boolean nextUpper = false;
for (int i = 0; i < underscore.length(); i++) {
char c = underscore.charAt(i);
if (c == '_') {
nextUpper = true;
} else {
if (nextUpper) {
sb.append(Character.toUpperCase(c));
nextUpper = false;
} else {
sb.append(Character.toLowerCase(c));
}
}
}
return sb.toString();
}
// 测试工具方法
public static void main(String[] args) {
System.out.println("isEmpty测试: " + isEmpty("")); // true
System.out.println("isEmpty测试: " + isEmpty(" ")); // false
System.out.println("isBlank测试: " + isBlank(" ")); // true
System.out.println("重复字符串: " + repeat("abc", 3)); // "abcabcabc"
System.out.println("首字母大写: " + capitalize("hello")); // "Hello"
System.out.println("驼峰转下划线: " + camelToUnderscore("userName")); // "user_name"
System.out.println("下划线转驼峰: " + underscoreToCamel("user_name")); // "userName"
}
}
7. 字符串常量池和intern()方法
7.1 字符串常量池概念
java
复制代码
// 字符串常量池示例
public class StringPoolDemo {
public static void main(String[] args) {
// 字符串字面量存储在常量池中
String str1 = "Hello";
String str2 = "Hello";
System.out.println("字面量相等: " + (str1 == str2)); // true
// new String()创建在堆中
String str3 = new String("Hello");
System.out.println("字面量与new比较: " + (str1 == str3)); // false
System.out.println("内容比较: " + str1.equals(str3)); // true
// intern()方法的使用
String str4 = str3.intern();
System.out.println("intern后比较: " + (str1 == str4)); // true
// 字符串拼接
String str5 = "He" + "llo"; // 编译时优化为"Hello"
System.out.println("编译时拼接: " + (str1 == str5)); // true
String prefix = "He";
String str6 = prefix + "llo"; // 运行时拼接
System.out.println("运行时拼接: " + (str1 == str6)); // false
System.out.println("intern运行时拼接: " + (str1 == str6.intern())); // true
}
}
7.2 内存分析
arduino
复制代码
堆内存:
├── 字符串常量池
│ └── "Hello" (str1, str2, str4指向这里)
└── 普通对象区
└── String对象 (str3指向这里,内容为"Hello")
8. 总结
8.1 核心要点
-
String类:
- 不可变字符串,线程安全
- 适合少量字符串操作
- 提供丰富的字符串处理方法
-
StringBuffer类:
- 可变字符串缓冲区,线程安全
- 适合多线程环境下的字符串构建
- 性能中等
-
StringBuilder类:
- 可变字符串缓冲区,线程不安全
- 适合单线程环境下的大量字符串操作
- 性能最佳
8.2 使用建议
| 使用场景 |
推荐类型 |
理由 |
| 字符串常量或很少修改 |
String |
不可变性,简单直观 |
| 单线程频繁拼接 |
StringBuilder |
性能最佳 |
| 多线程环境拼接 |
StringBuffer |
线程安全 |
| 格式化输出 |
String.format |
功能强大 |
| 大量字符串处理 |
StringBuilder + 工具方法 |
效率和可维护性 |
8.3 性能优化总结
- 避免在循环中使用String拼接
- 预估StringBuilder的初始容量
- 使用StringBuilder的链式调用
- 合理使用字符串常量池
- 选择合适的字符串比较方法
字符串处理是Java编程中的基础技能,正确理解和使用这三个类,能够写出更高效、更安全的代码。在实际开发中,根据具体场景选择合适的字符串处理方式,是每个Java开发者必须掌握的技能。
本文全面介绍了Java字符串处理的核心类和方法,包括详细的API说明、性能对比、最佳实践和实用工具,希望对Java字符串编程有所帮助。