博客
关于我
Java中为什么要重写 hashcode 和 equals 方法
阅读量:155 次
发布时间:2019-02-28

本文共 2262 字,大约阅读时间需要 7 分钟。

为什么要重写 hashcode 和 equals 方法

在面试Java初级开发时,提到自定义类在HashMap中存储时遇到的问题,往往会引发关于equalshashCode方法的讨论。很多候选人表示自己从未重写过这两个方法,这不仅会导致实际开发中遇到问题,还可能在面试中暴露对Java内存管理和集合机制的理解不足。本文将从HashMap的存储规则入手,解释为什么要重写hashCodeequals方法,以及它们的重要性。


1. 理解Hash算法与HashMap的高效性

Hash表(即哈希表)是一种高效的数据结构,能够在平均O(1)时间内完成查找、插入和删除操作。与传统的线性表(如ArrayList)相比,Hash表的平均查找时间从O(n/2)显著降低到O(1)。

Hash表的核心原理是通过将键(Key)和值(Value)映射到一个特定位置(Index),称为Hash值。Java中的HashMap采用了链地址法来解决Hash冲突。


2. 为什么要重写equals和hashCode方法

当我们将自定义对象存入HashMap时,如果不重写hashCodeequals方法,可能会遇到以下问题:

示例分析:WithoutHashCode.java

import java.util.HashMap;
class Key {
private Integer id;
public Key(Integer id) {
this.id = id;
}
// hashCode和equals方法被注释掉
}
public class WithoutHashCode {
public static void main(String[] args) {
Key k1 = new Key(1);
Key k2 = new Key(1);
HashMap
hm = new HashMap<>();
hm.put(k1, "Key with id is 1");
System.out.println(hm.get(k2));
}
}
  • 问题1:无法通过相同值的对象正确取值

    • hashCode方法未重写,k1k2hashCode值分别为它们的内存地址。由于k1k2是不同的对象,hashCode值不同,导致无法通过k2取到对应的值。
  • 问题2:无法正确判断对象相等

    • equals方法未重写,k1k2会被视为两个不同的对象,无法找到正确的链表节点。

重写方法后的效果

class Key {
private Integer id;
public Key(Integer id) {
this.id = id;
}
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) {
return false;
}
Key key = (Key) o;
return Objects.equals(id, key.id);
}
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
public class WithoutHashCode {
public static void main(String[] args) {
Key k1 = new Key(1);
Key k2 = new Key(1);
HashMap
hm = new HashMap<>();
hm.put(k1, "Key with id is 1");
System.out.println(hm.get(k2)); // 输出:"Key with id is 1"
}
}
  • 效果1:相同值的对象能正确取值

    • k1k2hashCode值相同,存储在同一个链表节点下。
  • 效果2:能正确判断对象相等

    • equals方法判断对象的id是否相等,确保k2能找到k1的链表节点。

3. 对面试问题的说明

在面试中,提到hashCodeequals方法时,可以深入探讨以下问题:

  • 你有没有重写过hashCode方法?

    • 回答:有,重写了hashCode方法,确保每个对象的hashCode与其属性值相关联。
  • 你在使用HashMap时有没有重写hashCodeequals方法?

    • 回答:是的,重写了这两个方法,以确保自定义对象能正确存储和查找。
  • 你是怎么写的?

    • 回答:我重写了hashCode方法,使用对象的属性值计算哈希码。同时,重写了equals方法,判断对象的属性是否相等。

结论

重写hashCodeequals方法的主要作用是确保自定义对象能像预期一样存储和查找。这种做法不仅避免了哈希冲突,还能保证HashMap正确地找到目标对象。对于开发人员来说,这是基础的OOP知识,熟练掌握它对项目开发和面试中都至关重要。

转载地址:http://fcpc.baihongyu.com/

你可能感兴趣的文章
npm的常用操作---npm工作笔记003
查看>>
npm的常用配置项---npm工作笔记004
查看>>
npm的问题:config global `--global`, `--local` are deprecated. Use `--location=global` instead 的解决办法
查看>>
npm编译报错You may need an additional loader to handle the result of these loaders
查看>>
npm设置淘宝镜像、升级等
查看>>
npm设置源地址,npm官方地址
查看>>
npm设置镜像如淘宝:http://npm.taobao.org/
查看>>
npm配置安装最新淘宝镜像,旧镜像会errror
查看>>
NPM酷库052:sax,按流解析XML
查看>>
npm错误 gyp错误 vs版本不对 msvs_version不兼容
查看>>
npm错误Error: Cannot find module ‘postcss-loader‘
查看>>
npm,yarn,cnpm 的区别
查看>>
NPOI
查看>>
NPOI之Excel——合并单元格、设置样式、输入公式
查看>>
NPOI初级教程
查看>>
NPOI利用多任务模式分批写入多个Excel
查看>>
NPOI在Excel中插入图片
查看>>
NPOI将某个程序段耗时插入Excel
查看>>
NPOI格式设置
查看>>
NPOI设置单元格格式
查看>>