您好,登录后才能下订单哦!
# Java中 hashCode() 方法如何使用
## 1. 什么是hashCode()
`hashCode()`是Java中`Object`类定义的一个原生方法,返回对象的整数哈希值。这个方法的主要作用是为哈希表数据结构(如`HashMap`、`HashSet`等)提供支持。
```java
public native int hashCode();
根据Java官方文档,hashCode()必须遵守以下约定:
equals()
比较相等,它们的hashCode必须相同哈希表通过hashCode将元素分布到不同的”桶”中,使得查找操作的时间复杂度接近O(1)。
// HashMap的getNode方法片段(JDK 17)
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
先比较hashCode可以快速排除不相等的对象,避免昂贵的equals()
调用。
equals()
比较的字段都应参与hashCode计算Java 7引入的便捷方法:
@Override
public int hashCode() {
return Objects.hash(name, age, address);
}
处理数组类型字段:
@Override
public int hashCode() {
return 31 * name.hashCode() + Arrays.hashCode(scores);
}
public class Employee {
private String name;
private int age;
private Department dept;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((dept == null) ? 0 : dept.hashCode());
return result;
}
}
Joshua Bloch在《Effective Java》中提出的方案:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + field1.hashCode();
result = 31 * result + field2.hashCode();
result = 31 * result + (int)(field3 ^ (field3 >>> 32));
return result;
}
使用@EqualsAndHashCode
注解:
@EqualsAndHashCode
public class Product {
private String id;
private String name;
private BigDecimal price;
}
private volatile int hashCode; // 延迟初始化
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = Objects.hash(field1, field2);
}
return hashCode;
}
错误示例:
// equals比较name但hashCode使用全部字段
@Override
public boolean equals(Object o) {
return this.name.equals(((Student)o).name);
}
@Override
public int hashCode() {
return Objects.hash(name, age); // 违反契约
}
Set<Employee> set = new HashSet<>();
Employee emp = new Employee("John");
set.add(emp);
emp.setName("Peter"); // 修改后hashCode改变
System.out.println(set.contains(emp)); // 可能返回false
public class Manager extends Employee {
private List<Employee> subordinates;
@Override
public int hashCode() {
return 31 * super.hashCode() + subordinates.hashCode();
}
}
枚举已提供合适的hashCode实现,通常不需要重写:
public enum Status {
ACTIVE, INACTIVE, PENDING;
// 自动使用ordinal()作为hashCode
}
public class CaseInsensitiveString {
private String s;
@Override
public int hashCode() {
return s.toLowerCase().hashCode();
}
}
@Test
public void testHashCodeContract() {
Person p1 = new Person("Alice", 30);
Person p2 = new Person("Alice", 30);
assertEquals(p1.hashCode(), p2.hashCode());
assertNotEquals(p1.hashCode(), new Person("Bob", 30).hashCode());
}
Map<Integer, Integer> hashDistribution = new HashMap<>();
for (int i = 0; i < 10000; i++) {
int hash = new MyObject(i).hashCode();
hashDistribution.merge(hash, 1, Integer::sum);
}
// 分析冲突率
正确实现hashCode()是编写高质量Java代码的关键技能。通过理解哈希原理、遵循实现规范并结合实际场景选择适当策略,可以确保你的类在哈希集合中表现良好。记住:好的hashCode实现应该平衡分布性、一致性和性能三个维度。
提示:在Java 14+中,可以考虑使用record类型,它会自动生成符合规范的equals()和hashCode()方法。
> public record Point(int x, int y) {} > ```
这篇文章共计约2000字,涵盖了hashCode()的核心概念、实现方法、注意事项和最佳实践,采用Markdown格式并包含代码示例。可根据需要调整具体细节或补充更多示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。