重写了equals()方法之后也必须重写hashCode()方法

我们都知道Java语言是完全面向对象的,在java中,所有的对象都是继承于Object类。Ojbect类中有两个方法equals、hashCode,这两个方法都是用来比较两个对象是否相等的。

在未重写equals方法我们是继承了object的equals方法,那里的 equals是比较两个对象的内存地址,显然我们new了2个对象内存地址肯定不一样

  • 对于值对象,==比较的是两个对象的值
  • 对于引用对象,比较的是两个对象的地址

默认的equals方法同==,一般来说我们的对象都是引用对象,要重写equals方法。

现在有一个学生对象,有属性学号跟姓名,现在我新建了一个学生对象,又从数据里查出一个学生对象,这两个对象的学号跟姓名都一样,那这两个对象是不是相等呢?一般情况下,除非你有特殊需求要处理,这两个对象是相等的,可如果用==去比较,返回的结果是错误的。

这时候我们就必须重写equlas方法了。如果学号是主键,在equals方法里,我们认为只要学号相同,就可以返回true。

hashCode方法也是可以用来比较两个对象是否相等的。但是我们很少使用,应该说是很少直接使用。hashCode方法返回的是一个int值,可以看做是一个对象的唯一编码,

hashCode主要为散列表(如HashMap)提供支持。
如果一个对象的equals没有被改写,那么在执行时无论调用多少次hashCode()总是返回相同的值(对象的内部地址转化为该数值)。
如果两个对象相等(equals相等),那么对应的hashCode也相等。
两个对象不相等(equals不相等),其对应的hashCode也不相等,这种规范不是必须的(亦即两个对象不相等,其对应的hashCode可能相等)。延伸理解,hashCode相等的两个对象不一定相等(equals相等)。但是建议开发者遵守为两个不同对象返回不同的散列码的规范(比如重写时,但是Object.hashCode()确实为不同的对象返回不同的hashCode),
这种可以提升hash tables的性能。
特殊情况:并不一定每次执行hashCode()方法都返回完全一样的值。(参考JavaDoc)尽管不常见,但是确实有些Java库实际上在不同执行的过程中返回不同的hashCode值,如 Google’s Protocol Buffers[size=medium][/size]

 

一般如果使用java中的Map对象进行存储时,他会自动调用hashCode方法来比较两个对象是否相等。

所以如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。

如上面的学生例子,如果学号相同,不管姓名相不相同,返回的hash值一定要是一样的,这时我们的hash值只与学号有关。

Java代码  

  1. public class Test    
  2.  {    
  3.      public static void main(String[] args)    
  4.      {    
  5.      HashMap hm = new HashMap();    
  6.          
  7.      hm.put(new key(1),new value(2));    
  8.      if(hm.containsKey(new key(1)))    
  9.       System.out.println(hm.get(new key(1)));    
  10.      else    
  11.       System.out.println("dont have such a key");    
  12.      }    
  13.  }    

 你每次new 一个新对象出来hashcode肯定不一样,所以你拿不到你要的key。

Java代码  

  1. class key    
  2.  {    
  3.      int i ;    
  4.      public key(int i)    
  5.      {    
  6.      this.i = i;    
  7.      }    
  8.      @Override    
  9.      public boolean equals(Object obj)    
  10.      {    
  11.      if(obj instanceof key)    
  12.      {    
  13.       if(((key)obj).i == i)    
  14.          return true;    
  15.      }    
  16.      return false;    
  17.      }    
  18.      @Override    
  19.      public int hashCode()    
  20.      {    
  21.      return i;    
  22.      }    
  23.  }    

 

1、重写equals方法时需要重写hashCode方法,主要是针对Map、Set等集合类型的使用;

a: Map、Set等集合类型存放的对象必须是唯一的;

b: 集合类判断两个对象是否相等,是先判断equals是否相等,如果equals返回TRUE,还要再判断HashCode返回值是否ture,只有两者都返回ture,才认为该两个对象是相等的。

2、由于Object的hashCode返回的是对象的hash值,所以即使equals返回TRUE,集合也可能判定两个对象不等,所以必须重写hashCode方法,以保证当equals返回TRUE时,hashCode也返回Ture,这样才能使得集合中存放的对象唯一。

c

Co

Cod

Code

时间: 2024-10-21 15:05:15

重写了equals()方法之后也必须重写hashCode()方法的相关文章

浅析hashCode方法

一.问题引入       谈到hashCode就不得不说equals方法,二者均在Object类里,由于Object类是所有类的基类,所以一切类里都可以重写这两个方法. 要想较清晰的理解,需要先知道容器Collection,Set,list,Map(key值不可重复),Set元素无序不重复,list元素有序可重复,那么JVM是如何确定不同的元素的呢?       难道是逐个比较么,那样效率就太低了,JVM采用hash的方法(hash地址不一定是实际的物理地址),看看这个地址上是否有内容,没的话就

浅谈Java中的hashcode方法

哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法. 一.hashCode方法的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到has

why在重写equals时还必须重写hashcode方法分享_java

复制代码 代码如下: public boolean equals(Object anObject) {    if (this == anObject) {        return true;    }    if (anObject instanceof String) {        String anotherString = (String)anObject;        int n = count;        if (n == anotherString.count) { 

重写equals方法和hashcode方法的作用

 重写equals方法和hashcode方法的作用 作用:区分同一个类的不同对象是否是同一个对象. 应用:在Hibernate 定义 Model实体类的 联合主键的时候用到. 举例说明: 1.数据库中的表teacher表,包括三个字段,id.name.level.其中id和name作为联合主键. 2.类在类的角度,如果想定义一个联合主键,使用多个属性作为实体类的关键字,那么方式为定义一个单独的类,里面包含多个属性,并且将这个类包含在原有类中. public class Teacher{     

为什么在重写 equals方法的同时必须重写 hashcode方法_java

我们都知道Java语言是完全面向对象的,在java中,所有的对象都是继承于Object类. 其 equals 方法比较的是两个对象的引用指向的地址,hashcode 是一个本地方法,返回的是对象地址值.Ojbect类中有两个方法equals.hashCode,这两个方法都是用来比较两个对象是否相等的. 为何重写 equals方法的同时必须重写 hashcode方法呢 可以这样理解:重写了 equals 方法,判断对象相等的业务逻辑就变了,类的设计者不希望通过比较内存地址来比较两个对象是否相等,而

JAVA中重写equals()方法的同时要重写hashcode()方法

object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true:注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码.如下:(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true (2)当obj1.ha

hashcode-关系多态的问题,为何重写了equals 却没有调用

问题描述 关系多态的问题,为何重写了equals 却没有调用 import java.util.*; class Name{ private String firstname,secondname; public Name(String firstname,String secondname){ this.firstname=firstname; this.secondname=secondname; } public String getFirstName(){return firstname

super-为什么子类重写父类方法之后还要调用父类同名方法

问题描述 为什么子类重写父类方法之后还要调用父类同名方法 为什么子类重写父类方法之后还要调用父类同名方法 比如public class A extends B { public void say ( ) { super.say ( ); } 为什么重写父类方法之后还要在方法体里面用super关键词调用父类的同名方法呢 解决方案 你可以不调用,这个你自定,不是必须 解决方案二: SubClasing用法--子类重写父类方法,父类直接调用实现方式子类调用父类方法子类调用父类方法 解决方案三: 我想到

java-关于android子类重写父类方法,方法体里面的方法的问题

问题描述 关于android子类重写父类方法,方法体里面的方法的问题 android中子类重写父类Activity方法,在onCreate这个方法的方法体里面有个setContentView方法,这个方法是调用外部方法吗,为什么前面没加this关键词,不是说方法的方法体里面调用外部方法要加this关键词,加了没加有什么区别 解决方案 不是调用外部方法,这是调用父类Activity中的方法 解决方案二: 子类重写父类的方法应注意的问题java 子类重写父类的方法应注意的问题java 子类重写父类的