重写hashCode()时最重要的原因就是:无论何时,对同一个对象调用hashCode()都应该生成同样的值。如果在将一个对象用put()方法添加进HashMap时产生一个hashCode()值,而用get()取出时却产生了另外一个 hashCode()值,那么就无法重新取得该对象了。所以,如果你的hashCode()方法依赖于对象中易变的数据,那用户就要小心了,因为此数据发生变化时,hashCode()就会产生一个不同的hash码,相当于产生了一个不同的“键”。
Object的hashCode()方法,返回的是当前对象的内存地址。下次如果我们需要取一个一样的“键”对应的键值对的时候,我们就无法得到一样的hashCode值了。因为我们后来创建的“键”对象已经不是存入HashMap中的那个内存地址的对象了。
1、 为什么要重载equal方法?
答案:因为Object的equal方法默认是两个对象的引用的比较,意思就是指向同一内存,地址则相等,否则不相等;如果你现在需要利用对象里面的值来判断是否相等,则重载equal方法。
2、 为什么重载hashCode方法?
答案:一般的地方不需要重载hashCode,只有当类需要放在HashTable、HashMap、HashSet等等hash结构的集合时才会 重载hashCode,那么为什么要重载hashCode呢?就HashMap来说,好比HashMap就是一个大内存块,里面有很多小内存块,小内存块 里面是一系列的对象,可以利用hashCode来查找小内存块hashCode%size(小内存块数量),所以当equal相等时,hashCode必 须相等,而且如果是object对象,必须重载hashCode和equal方法。
3、 为什么equals()相等,hashCode就一定要相等,而hashCode相等,却不要求equals相等?
答案:1、因为是按照hashCode来访问小内存块,所以hashCode必须相等。
2、HashMap获取一个对象是比较key的hashCode相等和equal为true。
之所以hashCode相等,却可以equal不等,就比如ObjectA和ObjectB他们都有属性name,那么hashCode都以name计算,所以hashCode一样,但是两个对象属于不同类型,所以equal为false。
4、 为什么需要hashCode?
答案:1、 通过hashCode可以很快的查到小内存块。
2、 通过hashCode比较比equal方法快,当get时先比较hashCode,如果hashCode不同,直接返回false。
===========================华丽的分割线============================
转载:http://ami1984.iteye.com/blog/683762
我们看一个简单的例子,就能更加清楚的理解上面的意思。假定我们写了一个类:Person (人),我们判断一个对象“人”是否指向同一个人,只要知道这个人的身份证号一直就可以了。
先来个没有重写Code类的hashcode()的例子吧,看看是什么效果:
package com.fit; import java.util.HashMap; /** * 身份证类 * * @author ZYD * */ public class Code { /** * 身份证号码,一旦确定就不能更改 */ private final int id; public int getId() { return id; } /** * 通过构造方法确定身份证号码 * * @param id */ public Code(int id) { this.id = id; } /** * 重写equals()方法 */ public boolean equals(Object o) { // 如果地址一样,则两个对象相同 if (this == o) { return true; } // 如果两个对象是同一类型,则比较其属性值是否都相同。如果都相同,则说明两个对象也相同;否则,说明这两个对象不相同。 if (o instanceof Code) { Code co = (Code) o; boolean b = (co.id == this.id); return b; } return false; } /** * 重写toString()方法 */ public String toString() { return "【身份证】:" + id; } /** * 测试 * @param args */ public static void main(String[] args) { HashMap<Code, Person> map = new HashMap<Code, Person>(); Person p1 = new Person(new Code(10001),"张三"); Person p2 = new Person(new Code(10002),"李四"); map.put(p1.getCode(), p1); map.put(p2.getCode(), p2); System.out.println("HashMap 中存放的人员信息:\n"+map); //张三改名为张山,身份证号不变。 Person p3 = new Person(new Code(10001),"张山"); map.put(p3.getCode(), p3); System.out.println("张三改名为张山后 HashMap 中存放的人员信息:\n"+map); //查找身份证为10001 的人员信息 System.out.println("查找身份证为:10001 的人员信息:"+map.get(new Code(10001))); } } /** * 人类 * @author Administrator * */ class Person { /** * 每一个成人都有一个身份证 */ private Code code; /** * 姓名 */ private String name; public Code getCode() { return code; } public void setCode(Code code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person() { } public Person(Code code, String name) { this.code = code; this.name = name; } /** * 重写equals()方法 当两个人得身份证号相同以及姓名相同时,表示这两个人是同一个人。 */ public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Person) { Person p = (Person) o; boolean b = this.code.equals(p.code) && this.name.equals(p.name); return b; } return false; } /** * 重写toString()方法 */ public String toString() { return "【姓名】:" + name + " "; } }
运行结果:
HashMap 中存放的人员信息:
{【身份证】:10002=【姓名】:李四 , 【身份证】:10001=【姓名】:张三 }
张三改名为张山后 HashMap 中存放的人员信息:
{【身份证】:10002=【姓名】:李四 , 【身份证】:10001=【姓名】:张三 , 【身份证】:10001=【姓名】:张山 }
查找身份证为:10001 的人员信息:null
从上面的结果可以看出:
我们所做的更新和查找操作都失败了。失败的原因就是我们的身份证类:Code 没有覆写hashCode()方法。这个时候,当查找一样的身份证号码的键值对的时候,使用的是默认的对象的内存地址来进行定位。这样,后面的所有的身份证号对象
new Code(10001) 产生的hashCode()值都是不一样的,所以导致操作失败。
重写Code类的hashcode(),代码上:
package com.fit; import java.util.HashMap; /** * 身份证类 * * @author ZYD * */ public class Code { /** * 身份证号码,一旦确定就不能更改 */ private final int id; public int getId() { return id; } /** * 通过构造方法确定身份证号码 * * @param id */ public Code(int id) { this.id = id; } /** * 重写equals()方法 */ public boolean equals(Object o) { // 如果地址一样,则两个对象相同 if (this == o) { return true; } // 如果两个对象是同一类型,则比较其属性值是否都相同。如果都相同,则说明两个对象也相同;否则,说明这两个对象不相同。 if (o instanceof Code) { Code co = (Code) o; boolean b = (co.id == this.id); return b; } return false; } /** * 重写hashcode()方法,以身份证号码作为hash码。 * * @return */ public int hashCode() { return id; } /** * 重写toString()方法 */ public String toString() { return "【身份证】:" + id; } /** * 测试 * @param args */ public static void main(String[] args) { HashMap<Code, Person> map = new HashMap<Code, Person>(); Person p1 = new Person(new Code(10001),"张三"); Person p2 = new Person(new Code(10002),"李四"); map.put(p1.getCode(), p1); map.put(p2.getCode(), p2); System.out.println("HashMap 中存放的人员信息:\n"+map); //张三改名为张山,身份证号不变。 Person p3 = new Person(new Code(10001),"张山"); map.put(p3.getCode(), p3); System.out.println("张三改名为张山后 HashMap 中存放的人员信息:\n"+map); //查找身份证为10001 的人员信息 System.out.println("查找身份证为:10001 的人员信息:"+map.get(new Code(10001))); } } /** * 人类 * @author Administrator * */ class Person { /** * 每一个成人都有一个身份证 */ private Code code; /** * 姓名 */ private String name; public Code getCode() { return code; } public void setCode(Code code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person() { } public Person(Code code, String name) { this.code = code; this.name = name; } /** * 重写equals()方法 当两个人得身份证号相同以及姓名相同时,表示这两个人是同一个人。 */ public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof Person) { Person p = (Person) o; boolean b = this.code.equals(p.code) && this.name.equals(p.name); return b; } return false; } /** * 重写toString()方法 */ public String toString() { return "【姓名】:" + name + " "; } }
运行效果:
HashMap 中存放的人员信息:
{【身份证】:10001=【姓名】:张三 , 【身份证】:10002=【姓名】:李四 }
张三改名为张山后 HashMap 中存放的人员信息:
{【身份证】:10001=【姓名】:张山 , 【身份证】:10002=【姓名】:李四 }
查找身份证为:10001 的人员信息:【姓名】:张山
相关推荐
Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.
重写equals和hashcode方法,学习和进步
为什么重写equals方法,还必须要重写hashcode方法
NULL 博文链接:https://zpointer.iteye.com/blog/1058337
下面小编就为大家带来一篇java中重写equals()方法的同时要重写hashcode()方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
关于重写equals,hashcode以及compareTo方法!
4、重写equals()方法5、为什么要重写hashCode()方法?6、什么时候需要重写hashCode()方法?7、重写hashCode()方法: 1、hashCode与equals两者之间的关系 如果两个对象相同(即用equals比较返回true),那么它们的...
主要给大家介绍了关于java中为什么重写equals时必须重写hashCode方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Object 类是所有类的父类,其 equals 方法比较的是两个对象的引用指向的地址,hashcode 是一个本地方法,返回的是对象地址值。他们都是通过比较地址来比较对象是否相等的
主要介绍了Java重写equals及hashcode方法流程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
面试官问我,为什么重写equals函数,必须重写hashCode函数,我当时就懵住了。 然后扯天扯地,然后面试官瞬间就饱了,痛定思痛,写下这篇博客 首先看String的equals源码 String重写了equals方法,引用指向同一个地址...
主要介绍了java中重写equals和重写hashCode()的相关资料,需要的朋友可以参考下
主要介绍了重写hashCode()和equals()方法详细介绍,涉及重写equals()方法,重写hashCode()方法,重写equals()而不重写hashCode()的风险等相关内容的介绍,具有一定借鉴价值,需要的朋友可以参考下
首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法
hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。 使用hashCode()和equals() hashCode()方法被用来获取给定对象的整数。这个整数被用来确定对象被...
个人学习终结成果:为什么要重新equals和hashCode方法?如何重写?站好马步需从j2se基础开始
2、为什么改写equals()的时候,总是要改写hashCode() 两个原则: hashCode()的返回值和equals()的关系如下: 如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。 如果x.equals(y)返回...
java 序列化和重写 hashCode 以及 equals 方法的例子
1.概述 2.为什么重写equels方法要重写hashcode方法 3.例子
NULL 博文链接:https://alpha2009.iteye.com/blog/570322