原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11477229.html

  这两个方法可能大多数新手都没重写过,为什么要重写更是不知道了,所以这里通过一个例子就说一下重写这两个方法的作用是什么!

  HashMap应该很多人都用到过, 正常情况下我都是用String类型作为key存数据的, 这种情况下:

  Map<String, String> mapStr = new HashMap<>();
mapStr.put("map", "mapValue");
String value = mapStr.get("map");
System.out.println(value);

  打印输出的肯定是 "mapValue"

  如果key传入的是一个对象呢 ? 来看一下这种情况:

public class EqualsMain {
private String id; public EqualsMain(String id){
this.id = id;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
}public static void main(String[] args){
EqualsMain equalsMain1 = new EqualsMain("10");
EqualsMain equalsMain2 = new EqualsMain("20");
EqualsMain equalsMain3 = new EqualsMain("10"); Map<Object , String> map = new HashMap<>();
map.put(equalsMain1, "map中的数据");
System.out.println(map.get(equalsMain3));
System.out.println("----------------------");
}
}

  我们传入一个EqualsMain对象

  运行代码结果打印的是 : null

  先不分析原因, 我们再对EqualsMain对象重写一下 hashCode()方法:

    @Override
public int hashCode() {
return id.hashCode();
}

  再运行一下代码:

  依然是: null

  我们再重写equals()方法:

    @Override
public boolean equals(Object obj) {
if (null == obj) return false;
if (obj instanceof EqualsMain && this.id.equals(((EqualsMain)obj).getId())){
return true;
}else {
return false;
}
}

  再运行代码:

  此时会打印: "map中的数据"

  贴上全部代码:

public class EqualsMain {
private String id; public EqualsMain(String id){
this.id = id;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} @Override
public int hashCode() {
return id.hashCode();
} @Override
public boolean equals(Object obj) {
if (null == obj) return false;
if (obj instanceof EqualsMain && this.id.equals(((EqualsMain)obj).getId())){
return true;
}else {
return false;
}
} public static void main(String[] args){
EqualsMain equalsMain1 = new EqualsMain("10");
EqualsMain equalsMain2 = new EqualsMain("20");
EqualsMain equalsMain3 = new EqualsMain("10"); Map<Object , String> map = new HashMap<>();
map.put(equalsMain1, "map中的数据");
System.out.println(map.get(equalsMain3));
System.out.println("----------------------");
}
}

  为什么会这样呢? 分析一下

  进入HashMap的put方法看一下:

    public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
    static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

  putVal()方法太长, 贴一部分:

    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
       //此处是关键
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
//省略其他代码............

  方法中标记的地方是关键 !

  HashMap每次put操作都会做如下判断操作:

  1️⃣首先判断找到的对象的hash值是否和要传入的对象的key的hash值相等(此处体现了重写hashCode()方法的重要性);

  2️⃣然后再判断传入的对象的key是否和找到的对象的key是否相等,此处用的是 == , 对象比较的是内存引用地址, 如果这里返回false的话;

  3️⃣再判断一下传入的key是否equals找到的对象的key(此处体现了重写equals()方法的重要性);

  如果 条件1️⃣符合且2️⃣和3️⃣中任意一个条件符合,则认定传入的对象和查找到的对象是同一个.

  如果不重写hashCode(), 将调用Object的hashCode()方法,此时返回的是内存引用地址, 两个new出来的对象内存引用地址当然是不同的,所以第一次会出现null的情况;

  如果不重写equals()方法, equals() 内部将调用 == 来判断两个对象是否相同,那么也是比较的对象内存引用地址, 同上, 也是null.

  至此,问题就解决了.

  结束

为什么重写hashCode()和equals()方法的更多相关文章

  1. 为什么要重写hashcode和equals方法?初级程序员在面试中很少能说清楚。

    我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...

  2. (转)为什么要重写 hashcode 和 equals 方法?

    作者丨hsm_computer cnblogs.com/JavaArchitect/p/10474448.html 我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候 ...

  3. HashMap中使用自定义类作为Key时,为何要重写HashCode和Equals方法

    之前一直不是很理解为什么要重写HashCode和Equals方法,才只能作为键值存储在HashMap中.通过下文,可以一探究竟. 首先,如果我们直接用以下的Person类作为键,存入HashMap中, ...

  4. 为什么要重写hashcode和equals方法

    我在面试 Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候选人直接说没写过.我就想,或许真的没写过,于是就再通过一个问题确认:你在用HashMap的时候,键(Key)部分, ...

  5. 重写hashcode和equals方法

    重写hashcode和equals方法 简乐君 2019-05-07 21:55:43 35481 收藏 191分类专栏: Java 文章标签: equals() hashcode()版权 一.前言我 ...

  6. 【转】 如何重写hashCode()和equals()方法

    转自:http://blog.csdn.net/neosmith/article/details/17068365 hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它 ...

  7. 如何重写hashCode()和equals()方法

    hashCode()和equals()方法可以说是Java完全面向对象的一大特色.它为我们的编程提供便利的同时也带来了很多危险.这篇文章我们就讨论一下如何正解理解和使用这2个方法. 如何重写equal ...

  8. Java 重写 hashCode() 和 equals() 方法

    1. hashCode 1.1 基本概念 hashCode 是 JDK 根据对象的地址算出来的一个 int 数字(对象的哈希码值),代表了该对象再内存中的存储位置. hashCode() 方法是超级类 ...

  9. 【java编程】重写HashCode和equals方法

    [一]重写equals方案的规则 equals方法本来的原则 1.类的每个实例本质上都是唯一的. 2.不关心类是否提供了“逻辑相等”的测试功能 3.超类已经覆盖了equals,从超类继承过来的行为对于 ...

  10. Hibernate中用到联合主键的使用方法,为何要序列化,为何要重写hashcode 和 equals 方法

    联合主键用Hibernate注解映射方式主要有三种: 第一.将联合主键的字段单独放在一个类中,该类需要实现java.io.Serializable接口并重写equals和hascode,再将该类注解为 ...

随机推荐

  1. kubernetes部署第一个应用案例

    对比有无-o wide参数的区别 kubectl get pod --all-namespaceskubectl get pod --all-namespaces -o wide如下,查看所有Pod信 ...

  2. 执行jar包指定main

    java包中多个main,需要指定执行java -cp iot-device-sdk-java-0.0.5-SNAPSHOT.jar com.inspur.iot.client.sample.paho ...

  3. js 鼠标经过和经过离开 导航实战案例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Selenium_使用execute_script执行JavaScript(11)

    selenium的包含的方法已能完全满足UI自动化,但是有些时候又不得不用到执行JS的情况,比如在一个富文本框中输入1W个字,使用send_keys方法将经历漫长的输入过程,如果换成使用JS的inne ...

  5. idea 开启 tomcat 热部署 的 具体流程 和 使用方式

    1前言 一直以来,使用idea做web开发修改html.jsp.js文件后,必须手动重新部署tomcat,最少都有等个6 -10 秒, 甚至有时候还提示找不到某个编译文件报错,重新编译整个项目,那得等 ...

  6. wget 工具使用

    wget http://xxxx 下载文件到当前文件夹 wget -V 显示wget的版本信息并退出 wget -v 打印详细信息 默认 wget -nv 关闭详细输出,但不进入安静模式 wget - ...

  7. 修正了Model1模式,进入如今盛行的的Model2模式,也就是MVC模式

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6513668601843548675/ 1.<JSP页面实际上就是Servlet> 2.<JSP页 ...

  8. [转]webpack——CommonsChunkPlugin

    作用虽然webpack4已经出来很久了,CommonsChunkPlugin也已经舍弃了,但是还是有很多项目是通过webpack3来打包的,对CommonsChunkPlugin各个配置项的认识还是比 ...

  9. scrollTop、scrollHeight与clientHeight

    MDN上概念 scrollTop:获取或设置一个元素的内容垂直滚动的像素数. scrollHeight:一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容. clientHeight:元素内部 ...

  10. idea 个人settings和好看的主题推荐

    idea  个人settings和好看的主题推荐 配置和主体搭配使用,效果最佳!!! 配置文件: 链接:https://pan.baidu.com/s/1K-oW9UNxUz_5XWz4Ru3_3w  ...