String.contentEquals() 用于安全高效地比较 String 与 CharSequence(如 StringBuilder)的内容是否相同,避免 toString() 创建新对象的开销;而 equals() 因类型检查失败返回 false。
string.contentequals() 是一个专门用于**内容比较**的方法,它能安全、高效地判断一个 string 与另一个字符序列(如 stringbuilder、stringbuffer 或 charsequence 子类)是否包含完全相同的字符序列,而无需额外创建新字符串。
为什么不用 equals()?
String.equals(Object) 只有在参数也是 String 类型时才可能返回 true;传入 StringBuilder 会直接返回 false(因为类型不匹配,且 StringBuilder 没有重写 equals() 来与 String 比较):
String s = "hello";
StringBuilder sb = new StringBuilder("hello");
System.out.println(s.equals(sb)); // false —— 类型不同,不比较内容
System.out.println(s.equals(sb.toString())); // true —— 但会新建 String 对象,有开销
contentEquals() 的正确用法
它接受任意实现 CharSequence 的对象(StringBuilder 正是其中之一),逐字符比对内容,不关心对象身份,也不创建中间字符串:
- 调用方必须是
String(不能反过来用StringBuilder.contentEquals(String),该方法不存在) - 参数可以是
StringBuilder、StringBuffer、String、CharBuffer等CharSequence实现 - 空值(
null)作为参数会抛出NullPointerException,需提前判空
String s = "abc123";
StringBuilder sb = new StringBuilder("abc123");
boolean same = s.contentEquals(sb); // true
注意事项与常见陷阱
-
区分大小写:和
equals()一样,默认区分大小写;如需忽略大小写,应先转为统一大小写再比较,或改用String.equalsIgnoreCase()配合toString()(但失去零拷贝优势) -
线程安全无关:
contentEquals()本身不涉及同步,但若StringBuilder在多线程中被并发修改,结果不可预测——确保比较时其内容已稳定 -
null 安全需手动处理:
if (sb != null && s.contentEquals(sb)) { ... }
对比 toString() + equals() 的性能差异
虽然 sb.toString().equals(s) 语义等价,但它会:
- 分配新的
char[]数组(即使内容相同) - 构造新的
String对象(触发字符串池检查等) - 在长字符串场景下带来明显 GC 和内存开销
而 s.contentEquals(sb) 直接遍历两个内部 char[],只做字符比对,无对象创建,更轻量。










