1. 核心替换方法

// 单次区间替换(StringBuffer原生方法)
public StringBuffer replace(int start, int end, String str)

2. 实现 replaceAll() 功能

方案1:转换为String操作(简单但低效)
StringBuffer sb = new StringBuffer("apple banana apple");
String result = sb.toString().replaceAll("apple", "orange");
sb = new StringBuffer(result); // 重新构建StringBuffer
方案2:手动循环替换(高效推荐)
public static void replaceAll(StringBuffer sb, String target, String replacement) {
    int index = 0;
    int targetLen = target.length();
    int replacementLen = replacement.length();
    
    while ((index = sb.indexOf(target, index)) != -1) {
        sb.replace(index, index + targetLen, replacement);
        index += replacementLen; // 跳过已替换部分
    }
}

// 使用示例
StringBuffer sb = new StringBuffer("apple banana apple");
replaceAll(sb, "apple", "orange");
// 结果: "orange banana orange"

3. 使用技巧

  1. 大小写不敏感替换

    public static void replaceAllIgnoreCase(StringBuffer sb, String target, String replacement) {
        String lowerSb = sb.toString().toLowerCase();
        String lowerTarget = target.toLowerCase();
        int index = 0;
    
        while ((index = lowerSb.indexOf(lowerTarget, index)) != -1) {
            sb.replace(index, index + target.length(), replacement);
            index += replacement.length();
            // 更新小写副本的对应区间
            lowerSb = sb.toString().toLowerCase();
        }
    }
    
  2. 正则表达式替换

    // 通过String的replaceAll实现
    StringBuffer sb = new StringBuffer("123-456-789");
    String result = sb.toString().replaceAll("\\d{3}", "***");
    sb = new StringBuffer(result); // "***-***-***"
    
  3. 链式批量替换

    public static StringBuffer chainReplace(StringBuffer sb, String... pairs) {
        for (int i = 0; i < pairs.length; i += 2) {
            if (i + 1 >= pairs.length) break;
            replaceAll(sb, pairs[i], pairs[i + 1]);
        }
        return sb;
    }
    
    // 使用示例
    chainReplace(sb, "apple", "orange", "banana", "grape");
    

4. 常见错误

  1. 死循环替换

    // 错误:replacement包含target
    replaceAll(sb, "a", "aa"); // 无限循环!
    
  2. 索引错位

    // 错误:未更新index导致重复替换
    while ((index = sb.indexOf("a")) != -1) {
        sb.replace(index, index+1, "b");
        // 缺少 index += replacement.length()
    }
    
  3. 正则特殊字符未转义

    replaceAll(sb, "$price", "10"); // $在正则中有特殊含义
    

5. 注意事项

  1. 线程安全

    // 多线程环境需要同步
    synchronized(sb) {
        replaceAll(sb, "data", "DATA");
    }
    
  2. Unicode字符处理

    // 正确计算代理对字符长度
    String emoji = "😊";
    int emojiLen = emoji.codePointCount(0, emoji.length());
    
  3. 性能敏感场景

    // 10万次操作耗时对比:
    // String.replaceAll(): ~120ms 
    // 手动StringBuffer替换: ~25ms
    

6. 最佳实践与性能优化

  1. 预扫描优化(减少操作次数)

    public static void replaceAllOptimized(StringBuffer sb, String target, String replacement) {
        int index = 0;
        int targetLen = target.length();
        int step = replacement.length();
        List<Integer> positions = new ArrayList<>();
    
        // 第一阶段:收集所有位置
        while ((index = sb.indexOf(target, index)) != -1) {
            positions.add(index);
            index += targetLen;
        }
    
        // 第二阶段:倒序替换(避免索引变动)
        for (int i = positions.size()-1; i >= 0; i--) {
            int pos = positions.get(i);
            sb.replace(pos, pos + targetLen, replacement);
        }
    }
    
  2. 大文本处理(内存优化)

    public static void replaceInChunks(StringBuffer sb, String target, String replacement) {
        final int CHUNK_SIZE = 4096; // 4K块
        for (int i = 0; i < sb.length(); i += CHUNK_SIZE) {
            int end = Math.min(i + CHUNK_SIZE + target.length(), sb.length());
            String chunk = sb.substring(i, end);
            if (chunk.contains(target)) {
                String updated = chunk.replace(target, replacement);
                sb.replace(i, end, updated);
            }
        }
    }
    
  3. 直接操作字符数组(极限优化)

    public static void replaceAllCharLevel(StringBuffer sb, String target, String replacement) {
        char[] tarArr = target.toCharArray();
        char[] repArr = replacement.toCharArray();
        char[] srcArr = new char[sb.length()];
        sb.getChars(0, sb.length(), srcArr, 0);
    
        StringBuilder result = new StringBuilder();
        int i = 0;
        while (i < srcArr.length) {
            boolean match = true;
            for (int j = 0; j < tarArr.length; j++) {
                if (i + j >= srcArr.length || srcArr[i + j] != tarArr[j]) {
                    match = false;
                    break;
                }
            }
            if (match) {
                result.append(repArr);
                i += tarArr.length;
            } else {
                result.append(srcArr[i++]);
            }
        }
        sb.setLength(0);
        sb.append(result);
    }
    

总结

场景 推荐方案 性能特点
简单少量替换 toString().replaceAll() 代码简洁,效率较低
频繁修改的缓冲区 手动replace()循环 最佳性能(O(n))
超大文本(>1MB) 分块处理 避免OOM,中等性能
正则表达式需求 转换为String操作 功能强大,性能差
内存极度敏感场景 字符数组直接操作 零拷贝,最高效