【Java基础整理】Java字符串处理,String、StringBuffer、StringBuilder

Java字符串处理详解,String、StringBuffer、StringBuilder

1. CharSequence接口概述

接口定义

CharSequence接口是char值的一个可读序列,是Java字符串处理的顶层接口。

实现类

Java中主要有三个类实现了CharSequence接口:

实现类 特点 用途
String 不可变字符串 一般字符串操作
StringBuffer 可变字符串,线程安全 多线程环境下的字符串构建
StringBuilder 可变字符串,线程不安全 单线程环境下的字符串构建

共同特征

  • 都被final修饰符修饰,无法被继承
  • 无法重写方法
  • 都提供了字符序列的基本操作方法

2. String类详解

2.1 String类特点

String类是描述字符串的类,具有以下特征:

  • 实现接口SerializableCharSequenceComparable接口
  • 不可变性: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 选择原则

  1. 字符串不变或少量操作 → 使用 String
  2. 单线程大量拼接 → 使用 StringBuilder
  3. 多线程大量拼接 → 使用 StringBuffer
  4. 格式化字符串 → 使用 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 核心要点

  1. String类

    • 不可变字符串,线程安全
    • 适合少量字符串操作
    • 提供丰富的字符串处理方法
  2. StringBuffer类

    • 可变字符串缓冲区,线程安全
    • 适合多线程环境下的字符串构建
    • 性能中等
  3. StringBuilder类

    • 可变字符串缓冲区,线程不安全
    • 适合单线程环境下的大量字符串操作
    • 性能最佳

8.2 使用建议

使用场景 推荐类型 理由
字符串常量或很少修改 String 不可变性,简单直观
单线程频繁拼接 StringBuilder 性能最佳
多线程环境拼接 StringBuffer 线程安全
格式化输出 String.format 功能强大
大量字符串处理 StringBuilder + 工具方法 效率和可维护性

8.3 性能优化总结

  1. 避免在循环中使用String拼接
  2. 预估StringBuilder的初始容量
  3. 使用StringBuilder的链式调用
  4. 合理使用字符串常量池
  5. 选择合适的字符串比较方法

字符串处理是Java编程中的基础技能,正确理解和使用这三个类,能够写出更高效、更安全的代码。在实际开发中,根据具体场景选择合适的字符串处理方式,是每个Java开发者必须掌握的技能。


本文全面介绍了Java字符串处理的核心类和方法,包括详细的API说明、性能对比、最佳实践和实用工具,希望对Java字符串编程有所帮助。

相关推荐
期待のcode3 小时前
Java虚拟机栈
java·开发语言·jvm
珂朵莉MM3 小时前
全球校园人工智能算法精英大赛-产业命题赛-算法巅峰赛 2025年度画像
java·人工智能·算法·机器人
芒克芒克3 小时前
本地部署SpringBoot项目
java·spring boot·spring
cute_ming3 小时前
关于基于nodeMap重构DOM的最佳实践
java·javascript·重构
sww_10263 小时前
Netty原理分析
java·网络
小突突突4 小时前
Spring框架中的单例bean是线程安全的吗?
java·后端·spring
iso少年4 小时前
Go 语言并发编程核心与用法
开发语言·后端·golang
掘金码甲哥4 小时前
云原生算力平台的架构解读
后端
码事漫谈4 小时前
智谱AI从清华实验室到“全球大模型第一股”的六年征程
后端
码事漫谈4 小时前
现代软件开发中常用架构的系统梳理与实践指南
后端