一篇搞定equals()、compareTo()、hashCode()方法

张开发
2026/4/12 8:09:00 15 分钟阅读

分享文章

一篇搞定equals()、compareTo()、hashCode()方法
在 Java 中equals()、compareTo()、hashCode()是操作对象的三个核心方法核心差异equals()判断是否相等compareTo()判断大小/顺序hashCode()为哈希表提供快速定位。1、equals() —— 判断对象逻辑相等Object类的原生方法所有对象默认拥有用于比较两个对象是否逻辑相等非内存地址。默认跟 完全一样比较对象内存地址。2、compareTo()——判断对象大小/排序ComparableT 接口的抽象方法必须实现接口才能使用比较两个对象的大小、先后顺序用于自然排序。返回值int三规则负数当前对象 目标对象0当前对象 目标对象正数当前对象 目标对象强制规范a.compareTo(b) 0 必须等价于 a.equals(b) 否则排序集合会bug3、hashCode()——获取对象哈希码Object类的原生方法返回对象的哈希值专为哈希表HashMap/HashSet快速定位元素返回值为int类型。重写规范equals() 相等的对象hashCode()必须相等equals() 不等的对象hashCode() 尽量不等提升哈希表效率4、黄金规范①重写 equals() 必须同时重写 hashCode() 否则 HashMap/HashSet 会存储重复对象彻底失效②compareTo() 与 equals() 结果必须一致否则 TreeSet/TreeMap 会错误去重③ vs equals()基本类型比值引用类型比内存地址equals()默认比地址重写后比逻辑内容5、场景用法场景1判断两个对象是否相等 → 用equals()适用判断对象内容是否相同如用户名、身份证、字符串示例自定义User类重写equals()比较姓名和年龄class User { private String name; private int age; // 重写equals比较name和age逻辑相等 Override public boolean equals(Object obj) { if (this obj) return true; // 地址相同直接相等 if (obj null || getClass() ! obj.getClass()) return false; User user (User) obj; return age user.age name.equals(user.name); } // 必须同时重写hashCode Override public int hashCode() { return Objects.hash(name, age); } } // 测试 public class Test { public static void main(String[] args) { User u1 new User(张三, 20); User u2 new User(张三, 20); System.out.println(u1.equals(u2)); // true逻辑相等 System.out.println(u1 u2); // false地址不同 } }场景2对象排序 → 用compareTo()适用数组/集合排序、TreeSet/TreeMap自动排序示例Student类按分数排序实现Comparableclass Student implements ComparableStudent { private String name; private int score; // 重写compareTo按分数升序排序 Override public int compareTo(Student o) { return this.score - o.score; // 分数小 → 排前面 } } // 测试排序 public class Test { public static void main(String[] args) { ListStudent list new ArrayList(); list.add(new Student(张三, 80)); list.add(new Student(李四, 60)); Collections.sort(list); // 依赖compareTo()排序 } }场景3哈希集合/映射HashSet/HashMap→ 必须用equals() hashCode()适用快速去重、快速查找Java 最常用场景问题不重写两个方法HashSet会存逻辑重复的对象因为默认比地址public class Test { public static void main(String[] args) { SetUser set new HashSet(); User u1 new User(张三, 20); User u2 new User(张三, 20); set.add(u1); set.add(u2); // 重写后set.size()1正确去重 // 不重写set.size()2错误存储重复对象 System.out.println(set.size()); } }

更多文章