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

本文共 2222 字,大约阅读时间需要 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/

你可能感兴趣的文章
mysql 视图,视图更新删除
查看>>
MySQL 触发器
查看>>
mysql 让所有IP访问数据库
查看>>
mysql 记录的增删改查
查看>>
MySQL 设置数据库的隔离级别
查看>>
MySQL 证明为什么用limit时,offset很大会影响性能
查看>>
Mysql 语句操作索引SQL语句
查看>>
MySQL 误操作后数据恢复(update,delete忘加where条件)
查看>>
MySQL 调优/优化的 101 个建议!
查看>>
mysql 转义字符用法_MySql 转义字符的使用说明
查看>>
mysql 输入密码秒退
查看>>
mysql 递归查找父节点_MySQL递归查询树状表的子节点、父节点具体实现
查看>>
mysql 通过查看mysql 配置参数、状态来优化你的mysql
查看>>
mysql 里对root及普通用户赋权及更改密码的一些命令
查看>>
Mysql 重置自增列的开始序号
查看>>
mysql 锁机制 mvcc_Mysql性能优化-事务、锁和MVCC
查看>>
MySQL 错误
查看>>
mysql 随机数 rand使用
查看>>
MySQL 面试题汇总
查看>>
MySQL 面试,必须掌握的 8 大核心点
查看>>