A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM张勇 高级黑马   /  2013-4-2 17:08  /  2128 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 HM张勇 于 2013-4-3 10:31 编辑

重写equals()后为什么一定要重写hashCode呢?

请详细解释下原理。

6 个回复

倒序浏览
equals比较得是两个对象,或者是两个对象的内容,假如两个对象相等那它们两个的hashcode也必须一样,因为hashcode是用对象的内部地址转换成一个整数的。
假如你改写了equals方法而没重写hashcode方法,那就乱套了!

这是sun说的,看看Object#equals()和Object#hashCode()的文档

     * Note that it is generally necessary to override the <tt>hashCode</tt>
     * method whenever this method is overridden, so as to maintain the
     * general contract for the <tt>hashCode</tt> method, which states
     * that equal objects must have equal hash codes.

     * Returns a hash code value for the object. This method is
     * supported for the benefit of hashtables such as those provided by
     * <code>java.util.Hashtable</code>.

回复 使用道具 举报
咳咳,先看一个小例子~~
  1. import java.util.HashSet;


  2. public class Student {

  3.         private String number;//学号
  4.        
  5.         public Student(String number) {
  6.                 this.number = number;
  7.         }

  8.         public String getNumber() {
  9.                 return number;
  10.         }

  11.         public void setNumber(String number) {
  12.                 this.number = number;
  13.         }
  14.        
  15.         @Override
  16.         public boolean equals(Object obj) {
  17.                 return (this.number == ((Student) obj).getNumber());
  18.         }
  19.        
  20.         @Override
  21.         public int hashCode() {
  22.                 int result = 17;
  23.         result = 37 * result + number.hashCode();
  24.         return result;
  25.         }

  26.         public static void main(String[] args) {
  27.                
  28.                 HashSet<Student> students = new HashSet<Student>();
  29.                 students.add(new Student("1"));
  30.                 students.add(new Student("1"));
  31.                 students.add(new Student("1"));
  32.                 System.out.println(students.size());
  33.         }
  34. }
复制代码


可以试着将hasHash方法注释然后打印结果,你会发现只有equal方法,set还是会判断这是两个不同的对象~~

这是为毛呢~~

看源码~~






再回过头来看hashCode方法的注释




评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
看你的目的那,所有的类都都会继承Object,而Objetc中的equals()方法,比较的是引用变量的地址.如果你想比较地址的话,就不用重写equals()方法.
但如果你想比较其它内容的话,就必须重写equals()方法,建立自已的方法,这样才能得到自已想要的结果.
懂了否?
回复 使用道具 举报
hashcode用于使用哈希表存储对象的集合
向这种集合时加入对象首先计算对象的hashcode(使用hashcode方法),每个hashcode对应一个存储空间(每个存储空间可以存放多个元素),加入元素时,会沿着存储空间的第一个元素开始比较(使用equals方法),知道存储空间的最后一个元素,如果没有相同的元素,就加入,否则返回false。
equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
回复 使用道具 举报
equals 是比较两个对象的内容是否相同, 每次都要去比较, 如果要比较多次的话效率就低, hashcode 是一个算法, 讲白一点就是把类分类 ,属性相同的必须相同,属性不同尽量不同, 这样可以减少equals 比较的次数 效率就高了,
回复 使用道具 举报
首先equals与hashcode间的关系是这样的:

1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;

2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)   

自我的理解:由于为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的

次数,这对比需要比较的数量很大的效率提高是很明显的,一个很好的例子就是在集合中的使用;

我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元素呢,但靠equals方法一样比较的

话,如果原来集合中以后又10000个元素了,那么放入10001个元素,难道要将前面的所有元素都进行比较,看看是否有重复,欧码噶的,这个效率可想而知,因此hashcode

就应遇而生了,java就采用了hash表,利用哈希算法(也叫散列算法),就是将对象数据根据该对象的特征使用特定的算法将其定义到一个地址上,那么在后面定义进来的数据

只要看对应的hashcode地址上是否有值,那么就用equals比较,如果没有则直接插入,只要就大大减少了equals的使用次数,执行效率就大大提高了。

继续上面的话题,为什么必须要重写hashcode方法,其实简单的说就是为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,如果重写了equals而未重写

hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equal都是根据对象的特征进行重写的),但hashcode确实不相同的

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马