优化 equals 性能需优先用 == 判同引用、常量放左防 npe、批量匹配改用 set、避免 equalsignorecase;自定义类首行加 this == obj 判断,字符串比较用 "str".equals(obj)。

频繁调用 equals 方法时,性能损耗主要来自重复计算、空检查开销、字符逐个比对、类型判断延迟以及哈希结构不匹配。优化核心是减少无效操作、利用短路逻辑、提前终止和适配数据结构。
优先用 == 做引用快速判等
多数场景中,两个对象大概率是同一实例(尤其在缓存、单例、池化对象中)。先用 this == obj 判断可立即返回,耗时 O(1),避免后续所有开销。
- String 字面量比较时,常量池内字符串天然满足该条件,
"abc".equals("abc")实际走的就是这一步 - 自定义类重写
equals时,第一行必须是if (this == obj) return true; - 注意:此优化仅适用于“可能为同一对象”的场景,不可跳过逻辑相等判断
把常量放左边防 NPE 并提升稳定性
当比较对象可能为 null 时,obj.equals("target") 易抛出 NullPointerException;而 "target".equals(obj) 不仅安全,还省去显式判空,JVM 对字符串字面量调用 equals 有额外内联优化。
- 推荐写法:
"user".equals(role),而非role != null && role.equals("user") - 该模式对所有不可变常量(如枚举名、配置键)均适用,且编译期可验证字面量非 null
批量字符串匹配改用 Set 而非链式 equals
若需判断一个字符串是否属于预设的多个值(如 status.equals("PENDING") || status.equals("PROCESSING") || ...),线性遍历时间复杂度为 O(n),n 增大时明显拖慢。
- 用
Set<string></string>预加载合法值,调用validStatuses.contains(input),平均查找 O(1) - 初始化时用
Set.of("PENDING", "PROCESSING", "COMPLETED")(Java 9+)或new HashSet(Arrays.asList(...)) - 若值固定且数量少(≤5),也可用
switch (str) { case "A": case "B": ... },JVM 会编译为 tableswitch,效率更高
避免 equalsIgnoreCase 的隐式开销
equalsIgnoreCase 内部需对每个字符做 Unicode 大小写映射,比普通 equals 多 2–3 倍耗时,且无法内联优化。
- 统一预处理:入库/接收时就转为小写并存储,后续全部用
equals比较 - 若仅少量字段需忽略大小写,可建专用字段(如
usernameLower),索引也更友好 - 绝对避免在循环体内调用
equalsIgnoreCase,应提取为input.toLowerCase()一次,再复用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











