参考答案:
在 Java 中,hashCode()
和 equals()
是用来定义对象的比较与哈希行为的两个核心方法。它们在集合框架(如 HashMap
、HashSet
)中有着重要的作用,直接影响对象的存储和查找性能。
hashCode()
Object
类中:
1public native int hashCode();
equals()
1public boolean equals(Object obj) { 2 return (this == obj); 3}
Java 中规定了 hashCode()
和 equals()
的契约关系:
equals()
比较相等,则它们的 hashCode()
必须相等。hashCode()
不相等,则它们一定不相等。hashCode()
相等,它们不一定通过 equals()
比较相等。示例:
1class Person { 2 String name; 3 4 Person(String name) { 5 this.name = name; 6 } 7 8 @Override 9 public boolean equals(Object obj) { 10 if (this == obj) return true; 11 if (obj == null || getClass() != obj.getClass()) return false; 12 Person person = (Person) obj; 13 return name.equals(person.name); 14 } 15 16 @Override 17 public int hashCode() { 18 return name.hashCode(); 19 } 20}
hashCode()
提高效率:
HashMap
、HashSet
)中,hashCode()
用于快速找到对象所在的“桶”。equals()
再进一步比较以确认对象是否相等。单独依赖 equals()
的缺陷:
equals()
,每次查找都需要遍历集合中的每个元素,性能较低。hashCode()
的引入减少了比较次数。哈希冲突的处理:
hashCode()
相等,仍可能发生冲突。此时,集合会调用 equals()
方法进一步比较。1import java.util.HashSet; 2 3class Person { 4 String name; 5 6 Person(String name) { 7 this.name = name; 8 } 9 10 @Override 11 public boolean equals(Object obj) { 12 if (this == obj) return true; 13 if (obj == null || getClass() != obj.getClass()) return false; 14 Person person = (Person) obj; 15 return name.equals(person.name); 16 } 17 18 @Override 19 public int hashCode() { 20 return name.hashCode(); 21 } 22} 23 24public class Main { 25 public static void main(String[] args) { 26 HashSet<Person> set = new HashSet<>(); 27 set.add(new Person("Alice")); 28 System.out.println(set.contains(new Person("Alice"))); // 输出: true 29 } 30}
为什么重写 equals()
后必须重写 hashCode()
?
hashCode()
,默认实现可能导致相等的对象有不同的哈希码,导致哈希集合(如 HashMap
)无法正常工作。hashCode()
和 equals()
没有遵守约定会怎样?
HashSet
中可能出现相等对象重复存储。如何设计 hashCode()
?
Objects.hash()
或 Apache Commons Lang
的 HashCodeBuilder
。是否可以只重写 hashCode()
而不重写 equals()
?
equals()
定义了对象的逻辑相等性,如果只重写 hashCode()
会导致错误的相等判断。错误情况:
1class Person { 2 String name; 3 4 Person(String name) { 5 this.name = name; 6 } 7} 8 9public class Main { 10 public static void main(String[] args) { 11 HashSet<Person> set = new HashSet<>(); 12 set.add(new Person("Alice")); 13 System.out.println(set.contains(new Person("Alice"))); // 输出: false 14 } 15}
修复:
1@Override 2public boolean equals(Object obj) { 3 if (this == obj) return true; 4 if (obj == null || getClass() != obj.getClass()) return false; 5 Person person = (Person) obj; 6 return name.equals(person.name); 7} 8 9@Override 10public int hashCode() { 11 return name.hashCode(); 12}
最近更新时间:2024-12-09