字符串内容比较必须用equals()而非==,因==只比较引用;equals()安全处理null并逐字符比对,Objects.equals()更稳妥;compareTo()用于字典序排序,返回整数不可替代equals()。

用 equals() 判断字符串是否相等,不是 ==
Java 中字符串内容比较必须用 equals(),== 只比较引用是否指向同一对象。哪怕两个字符串字面值完全一样,如果来自不同创建方式(比如一个字面量、一个 new String()),== 就返回 false。
常见错误现象:
String a = "hello";
String b = new String("hello");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
-
equals()会先检查null,再逐字符比对内容,安全可靠 - 始终用
Objects.equals(str1, str2)更稳妥,能自动处理任一参数为null的情况 - 不要写
str.equals("abc")这种形式——万一str是null就抛NullPointerException;应写成"abc".equals(str)或用Objects.equals()
compareTo() 返回整数,用于排序和字典序判断
compareTo() 是 Comparable 接口定义的方法,返回负数、0 或正数,表示当前字符串在字典序中“小于”“等于”或“大于”参数字符串。它不返回布尔值,不能替代 equals() 做相等判断。
使用场景:集合排序(如 TreeSet、Collections.sort())、自定义比较逻辑、需要知道大小关系而非仅是否相等时。
- 返回值含义:
0表示内容完全相等;负数(如-1)只代表“小”,不一定是-1;正数同理 - 区分大小写:默认按 Unicode 码点比较,
"Apple".compareTo("apple") (因为大写A码点更小) - 如需忽略大小写,用
compareToIgnoreCase(),但注意它不遵守 locale 规则(比如土耳其语的i/I特殊映射需用Collator)
性能与兼容性:equals() 和 compareTo() 都是 O(n),但用途不可互换
两者时间复杂度都是线性,最坏情况下遍历全部字符。但它们设计目标完全不同:
立即学习“Java免费学习笔记(深入)”;
-
equals()是语义相等性判断,关注“是不是同一个内容”,结果只有true/false -
compareTo()是序关系定义,关注“谁在字典里排前面”,结果是三态整数,支撑排序和范围查找 - 不要用
compareTo() == 0替代equals()—— 虽然结果一致,但语义模糊、可读性差,且某些工具(如 IDE、静态分析器)可能报 warning - 在
switch表达式(Java 14+)中,只能用equals()或==(对常量),不能用compareTo()
容易被忽略的细节:空字符串、null、locale 敏感场景
真实业务中,字符串比较常遇到边界情况,光靠基础方法不够。
- 空字符串
""和null必须显式处理,equals()对null参数返回false,但不会 NPE;compareTo()遇到null直接抛NullPointerException - 国际化场景下,简单
compareTo()可能违反用户预期(例如德语中ä应等价于ae),此时应使用Collator.getInstance(locale).compare(s1, s2) - 数据库字段比较、配置项匹配等场景,建议统一用
StringUtils.equals(a, b)(Apache Commons Lang),它对null安全、可读性强










