跳转至

String类

String是Java开发中非常高频使用的一个类

重要

它有两个子类,StringBuffer 和 StringBuilder 在项目中也会被高频使用

classDiagram
    class String {
        -final char[] value
        +length() int
        +charAt(int) char
        +substring(int) String
        +equals(Object) boolean
    }
    class StringBuilder {
        +append(String) StringBuilder
        +toString() String
    }
    class StringBuffer {
        +append(String) StringBuffer
        +toString() String
    }
    String <.. StringBuilder
    String <.. StringBuffer

对比

特点 String StringBuilder StringBuffer
可变性 不可变 可变 可变
线程安全
性能 较差 最好 较好
适用场景 少量字符串操作 单线程大量字符串操作 多线程大量字符串操作
内存使用 每次修改都创建新对象 动态扩容,内存效率高 动态扩容,内存效率高
同步机制 不需要 不需要 需要
初始容量 16 16
扩容策略 不适用 2倍+2 2倍+2

示例代码

public class StringDemo {
    public static void main(String[] args) {
        // 字符串创建
        String s1 = "hello"; // 字符串常量池
        String s2 = new String("hello"); // 堆中新对象
        String s3 = "hello";

        // == 和 equals比较
        System.out.println("s1 == s2: " + (s1 == s2)); // false
        System.out.println("s1 == s3: " + (s1 == s3)); // true
        System.out.println("s1 equals s2: " + s1.equals(s2)); // true

        // 常用方法
        System.out.println("长度: " + s1.length());
        System.out.println("拼接: " + s1.concat(" world"));
        System.out.println("子串: " + "hello".substring(1, 3)); // el
        System.out.println("替换: " + "hello".replace('l', 'L')); // heLLo
        System.out.println("分割: " + Arrays.toString("a,b,c".split(",")));

        // 字符串拼接性能
        long start = System.currentTimeMillis();
        String result = "";
        for(int i = 0; i < 10000; i++) {
            result += i; // 性能差,每次创建新对象
        }
        long end = System.currentTimeMillis();
        System.out.println("普通拼接耗时: " + (end - start) + "ms");

        // 使用StringBuilder优化
        start = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < 10000; i++) {
            sb.append(i);
        }
        end = System.currentTimeMillis();
        System.out.println("StringBuilder耗时: " + (end - start) + "ms");

        // 其他常用方法
        System.out.println("是否包含: " + "hello".contains("ell")); // true
        System.out.println("去除空格: " + " hello ".trim()); // hello
        System.out.println("格式化: " + String.format("姓名:%s, 年龄:%d", "张三", 25));
    }
}
public class StringBufferDemo {
    public static void main(String[] args) {
        // 创建StringBuffer对象
        StringBuffer sb = new StringBuffer();

        // 追加字符串
        sb.append("Hello");
        sb.append(" ");
        sb.append("World");
        System.out.println("追加后: " + sb.toString());

        // 插入字符串
        sb.insert(5, " Java");
        System.out.println("插入后: " + sb.toString());

        // 删除字符串
        sb.delete(5, 10);
        System.out.println("删除后: " + sb.toString());

        // 替换字符串
        sb.replace(0, 5, "Hi");
        System.out.println("替换后: " + sb.toString());

        // 反转字符串
        sb.reverse();
        System.out.println("反转后: " + sb.toString());

        // 设置长度
        sb.setLength(5);
        System.out.println("设置长度后: " + sb.toString());

        // 获取容量
        System.out.println("当前容量: " + sb.capacity());

        // 确保容量
        sb.ensureCapacity(50);
        System.out.println("确保容量后: " + sb.capacity());
    }
}
public class StringBuilderDemo {
    public static void main(String[] args) {
        // 创建StringBuilder对象
        StringBuilder sb = new StringBuilder();

        // 追加字符串
        sb.append("Hello");
        sb.append(" ");
        sb.append("World");
        System.out.println("追加后: " + sb.toString());

        // 插入字符串
        sb.insert(5, " Java");
        System.out.println("插入后: " + sb.toString());

        // 删除字符串
        sb.delete(5, 10);
        System.out.println("删除后: " + sb.toString());

        // 替换字符串
        sb.replace(0, 5, "Hi");
        System.out.println("替换后: " + sb.toString());

        // 反转字符串
        sb.reverse();
        System.out.println("反转后: " + sb.toString());

        // 设置长度
        sb.setLength(5);
        System.out.println("设置长度后: " + sb.toString());

        // 获取容量
        System.out.println("当前容量: " + sb.capacity());

        // 确保容量
        sb.ensureCapacity(50);
        System.out.println("确保容量后: " + sb.capacity());

        // 链式调用
        StringBuilder chain = new StringBuilder()
            .append("Hello")
            .append(" ")
            .append("World")
            .insert(5, " Java")
            .delete(5, 10)
            .replace(0, 5, "Hi");
        System.out.println("链式调用结果: " + chain.toString());
    }
}

使用场景

String使用场景

  1. 字符串常量定义

    String name = "张三";
    String path = "/api/v1/users";
    

  2. 字符串比较和查找

    if (userName.equals("admin")) {
        // 处理管理员逻辑
    }
    

  3. 字符串分割和截取

    String[] parts = "a,b,c".split(",");
    String sub = "hello".substring(0, 2);
    

  4. 字符串格式化

    String message = String.format("用户%s的年龄是%d", name, age);
    

StringBuilder使用场景

  1. 大量字符串拼接

    StringBuilder sql = new StringBuilder();
    sql.append("SELECT * FROM users WHERE 1=1");
    if (name != null) {
        sql.append(" AND name = '").append(name).append("'");
    }
    

  2. 动态构建HTML/XML

    StringBuilder html = new StringBuilder();
    html.append("<div>")
        .append("<h1>").append(title).append("</h1>")
        .append("<p>").append(content).append("</p>")
        .append("</div>");
    

  3. 日志信息构建

    StringBuilder log = new StringBuilder();
    log.append("用户登录失败:")
       .append("用户名=").append(username)
       .append(", IP=").append(ip)
       .append(", 时间=").append(new Date());
    

StringBuffer使用场景

  1. 多线程环境下的字符串操作

    public class LogBuffer {
        private StringBuffer buffer = new StringBuffer();
    
        public synchronized void appendLog(String message) {
            buffer.append(new Date()).append(": ").append(message).append("\n");
        }
    }
    

  2. 线程安全的字符串构建器

    public class ThreadSafeBuilder {
        private StringBuffer buffer = new StringBuffer();
    
        public void buildMessage(String part) {
            buffer.append(part);
        }
    
        public String getResult() {
            return buffer.toString();
        }
    }
    

  3. 并发环境下的日志记录

    public class ConcurrentLogger {
        private StringBuffer logBuffer = new StringBuffer();
    
        public void log(String message) {
            synchronized(logBuffer) {
                logBuffer.append(Thread.currentThread().getName())
                        .append(": ")
                        .append(message)
                        .append("\n");
            }
        }
    }
    

选择建议

  1. 如果字符串内容固定,使用String
  2. 如果单线程下需要频繁修改字符串,使用StringBuilder
  3. 如果多线程下需要频繁修改字符串,使用StringBuffer
  4. 如果字符串操作次数较少,直接使用String即可
  5. 如果字符串操作次数较多,优先考虑StringBuilder(单线程)或StringBuffer(多线程)