解决这个问题得先明白:hashCode 方法用于散列集合的查找,equals 方法用于判断两个对象是否相等。

第一步:具体背景(没有背景的讨论就是在耍流氓)

以HashMap中put方法为背景

第二步:分析源代码:

  public V put(K key, V value) {    

         if (key == null)
return putForNullKey(value); //通过key的hashcode计算hash值
int hash = hash(key.hashCode());
//通过hash值和table数组的长度计算出元素存放在table数组的位置
int i = indexFor(hash, table.length); //table[i]的位置已经存在元素,遍历链表
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k; //调用 equals 方法判断key是否相等,若相等,该key对应的键值对已经存在,用新的value取代旧的value
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
} modCount++;
// 若该key对应的键值对不存在,将key-value封装成Entry对象添加到table[i]处 ,头插法。
addEntry(hash, key, value, i);
return null;
}

HashMap 的 put 方法实际上是先调用 hashCode 定位到数组的位置
如果该数组的位置上已经存在元素了,即 table[i] != null,那么遍历链表,调用 equals 方法判断key是否相等。如果相等,表明这个key对应的键值对已经存在,那么新的 value 会覆盖掉旧的 value。如果遍历链表都没有找到key,那么表明这个 key 对应的键值对不存在,直接插入头部,作为链表的头节点。


总结Hashmap的put方法流程:

1.向HashMap添加元素的时候,需要先定位到在数组的位置(采用hashCode方法)。

2.如果只重写了 equals 方法,两个键的 equals 返回了true,集合是不允许出现重复键的,只能插入一个。

3.此时如果没有重写 hashCode 方法,那么就无法定位到同一个位置,集合还是会插入键。这样集合中就出现了重复键了。那么重写的equals方法就没有意义了。所以一定要重写!

如下图:

为什么重写了equals(),还要重写hashCode()?的更多相关文章

  1. 为什么重写equals还要重写hashcode??

    equals和hashcode是object类下一个重要的方法,而object类是所有类的父类,所以所有的类都有这两个方法 equals和hashcode间的关系: 1.如果两个对象相同(即equal ...

  2. 为什么重写了equals() 就要重写hashcode()

    规定:1.两个对象相等,则hashcode也一定是相等的:2.两个对象相等,对两个对象分别调用equals()都返回 true:3.两个对象有相同的hashcode,但不一定相等 为什么重写了equa ...

  3. 为什么重写equals还要重写hashcode

    参考回答: HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地址,这样即便有相同含义的两 ...

  4. 为什么重写equals()必须重写hashCode()

    主要原因是因为hashCode是用对象的内部地址转换成一个整数的,而equals比较得是两个对象,或者是两个对象的内容 如果你重写了equals,而保留hashCode的实现不变,那么很可能两个对象明 ...

  5. 详解equals()方法和hashCode()方法

    前言 Java的基类Object提供了一些方法,其中equals()方法用于判断两个对象是否相等,hashCode()方法用于计算对象的哈希码.equals()和hashCode()都不是final方 ...

  6. java基础解析系列(十一)---equals、==和hashcode方法

    java基础解析系列(十一)---equals.==和hashcode方法 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系 ...

  7. static,final关键字,Object类的tostring方法,equals方法,hashCode方法

    1)static关键字 static可以修饰:属性.方法.代码块 静态方法不能访问非静态 属性 或 方法 属性(变量): 成员变量: 静态变量: 通过 类名.静态变量来访问 通过 对象名.静态变量来访 ...

  8. 详解 equals() 方法和 hashCode() 方法

    创建实体类时,最好重写超类(Object)的hashCode()和equals()方法 equals()方法: 通过该实现可以看出,Object类的实现采用了区分度最高的算法,即只要两个对象不是同一个 ...

  9. equals()方法和hashCode()方法详解

    equals()方法和hashCode()方法详解 1. Object类中equals()方法源代码如下所示: /** * Object类中的equals()方法 */ public boolean ...

随机推荐

  1. 渗透神器CobaltStrike 3.1.2 去后门破解版 & Windows版TeamServer【转】

    转自我八师傅博客 CS简介 Cobalt Strike(简称CS)是全球黑客公认一款非常优秀的渗透测试神器,以metasploit为基础的GUI的框架式渗透工具,集成了传统远控功能(远程桌面VNC.键 ...

  2. poj 2081 Recaman's Sequence (dp)

    Recaman's Sequence Time Limit: 3000MS   Memory Limit: 60000K Total Submissions: 22566   Accepted: 96 ...

  3. 2019-2020-1 20199319《Linux内核原理与分析》第九周作业

    进程的切换和系统的一般执行过程 进程调度的时机 1.中断:起到切出进程指令流的作用.中断处理程序是与进程无关的内核指令流.中断类型: 硬中断:可屏蔽中断和不可屏蔽中断.高电平说明有中断请求. 软中断/ ...

  4. Golang中的匿名函数(闭包)

    GO语言的匿名函数就是闭包,以下是<GO语言编程>中对闭包的解释 基本概念闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代 ...

  5. MVC 事物

    前一阵学习mvc但是对于关联表的数据操作总是分裂开来写,这样有很大的侥幸,比如嵌套了3个 if(){ if(){ if(){ } } } 如果前两个都是true那么最后一个是false了,这样是不想看 ...

  6. dedecms织梦移站后替换数据库中文件路径命令

    1.系统设置路径替换 update dede_sysconfig set value='http://afish.cnblogs.com' where varname='cfg_basehost'; ...

  7. string::empty

    bool empty() const noexcept;注:判断string对象是否为空,为空返回true #include <iostream>#include <string&g ...

  8. 使用rpm安装mysql5.6(简单安装 实验使用)

    [root@localhost mysql]# cd /usr [root@localhost mysql]# mkdir mysql [root@localhost mysql]# cd mysql ...

  9. 在JavaScript中,++在前和++在后有什么区别

    一.++可以与输出语句写在一起,++写在变量前和写在变量后不是一个意思++ i 和 i ++ 区别在于运算顺序和结合方向. 在JavaScript中有两种自加运算,其运算符均为 ++,功能为将运算符自 ...

  10. echarts常用的配置项

    最近使用echarts可视化的业务,但是有一些配置项需要修改,把这段时间的学习总结一下 1. 修改默认配置 a. 去掉分割线和网格线,在xAxis或者yAxis中设置 splitLine: { sho ...