在Java中如何使用String类处理文本_Java字符串常用操作解析

Java中字符串比较应使用equals()而非==,因==比较内存地址而equals比较内容;substring索引需防越界;replace不支持正则而replaceAll支持;循环拼接用StringBuilder更高效;字符串不可变导致每次操作都生成新对象。

String.equals() 为什么不能用 == 比较字符串内容

Java 中 == 比较的是两个引用是否指向同一块内存地址,而 equals() 才真正比较字符序列是否一致。很多初学者在判断字符串值相等时误用 ==,导致逻辑出错,尤其在从用户输入、配置文件或网络读取字符串后。

  • 字符串字面量(如 "hello")在常量池中复用,"a" == "a" 返回 true;但 new String("a") == "a"false
  • 推荐统一使用 str1.equals(str2),避免空指针——更安全的写法是 "abc".equals(str)(把字面量放前面)
  • 忽略大小写用 equalsIgnoreCase(),比如验证 HTTP 方法时:method.equalsIgnoreCase("post")

substring() 的索引边界容易越界

substring(int beginIndex, int endIndex)endIndex 是**不包含**的,且两个参数都必须满足 0 ≤ beginIndex ≤ endIndex ≤ length(),否则抛 StringIndexOutOfBoundsException

  • 常见错误:想取最后 3 个字符写成 s.substring(s.length() - 3, s.length()),但当 s.length() 时直接崩溃
  • 稳妥做法是先判断长度:
    if (s.length() >= 3) {
        tail = s.substring(s.length() - 3);
    }
  • substring(beginIndex) 等价于 substring(beginIndex, length()),可省略第二个参数

replace() 和 replaceAll() 的根本区别在正则支持

replace(CharSequence target, CharSequence replacement) 做**字面量替换**,不解析正则;而 replaceAll(String regex, String replacement) 第一个参数是正则表达式,功能强但易出错。

  • 想把所有 "." 替换成 "-",用 replace(".", "-") 即可;若误用 replaceAll(".", "-"),会把每个字符都替换成 "-"(因为 . 在正则中是通配符)
  • 真要正则替换,需转义:replaceAll("\\.", "-");或者用 Pattern.quote(".") 包装
  • 性能上,replace() 更快,无正则引擎开销,日常简单替换优先选它

字符串拼接用 StringBuilder 还是 + 号

在循环内反复拼接字符串时,用 + 会隐式创建多个 StringBuilder 实例,造成对象频繁分配和 GC 压力;而显式用 StringBuilder 可复用缓冲区,适合大量拼接场景。

  • 方法内单次拼接(如 "Name: " + name + ", A

    ge: " + age
    )会被编译器自动优化为 StringBuilder,无需手动改
  • 循环中拼接必须用 StringBuilder
    StringBuilder sb = new StringBuilder();
    for (String s : list) {
        sb.append(s).append(",");
    }
    String result = sb.toString();
  • 注意 StringBuilder 非线程安全;多线程环境下考虑 StringBuffer(但多数情况不需要)

字符串不可变性是贯穿所有操作的基础约束——每次“修改”实际都生成新对象,原字符串不变。这个特性决定了缓存、安全性和性能表现,也解释了为什么像 trim()toUpperCase() 都返回新实例而不是就地修改。