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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lzw123451 中级黑马   /  2013-2-25 14:20  /  2137 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

我们知道
HashSet底层结构是哈希表
HashSet是通过元素的两个方法,hashCode盒equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals.

定义一个Student类
class Student
{
     String name;
     int   age;
   Student(String name,int age)
   {
       this.name=name;
       this.age = age;
    }

     public int hashCode()
  {
      return name.hashCode()+age*37;
  }

   public boolean equals(Object obj)
  {
          if(!(Obj instanceof Student))
                 return false;
         Student s = (Student)obj;
         return this.name.equals(s.name)&&this.age == s.age;

  }
}

这个类覆盖了Object类的 hashCode和equals方法

我的问题是 既然hashCode的返回值是根据对象的属性name和agel来确定的,也就是说只要这两个属性相等hashCode返回值就相等,
那么这样在hashSet中直接判断equals方法就可以确定他们是不是同一个元素了,hashCode方法不是多此一举吗?

5 个回复

倒序浏览
本帖最后由 黑马刘杰 于 2013-2-25 14:35 编辑

可以这么说hashCode指向内存地址,我们的对象输出的就是经过hashCode运算后的内存地址。
equals用于比较两个对象是否相同不是只看内存地址是否相同。
Java对于eqauls方法和hashCode方法是这样规定的:
1、如果两个对象相同,那么它们的hashCode值一定要相同;
2、如果两个对象的hashCode相同,它们并不一定相同
你重写了equals,比较的是对象保存的内容,这样子就会出现equals一样,hashCode不同的对象了
回复 使用道具 举报
当此equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码
回复 使用道具 举报
本帖最后由 夏振博 于 2013-2-25 14:43 编辑

1.获取元素的哈希码值(使用元素的hashCode()方法);
2.通过哈希码值计算桶位(可以把哈希码值理解为就是桶位);
3.遍历桶中元素,使用元素的equals()方法,验证元素是否在桶中已经存在;
存在则添加失败,否则把元素添加到桶中
分别添加"abc"和"cba"计算的哈希码值相同,但是它们的元素是相同的吗?这需要再次判断!
你的代码里name.hashCode()+age*37;
假如:name.hashCode()计算得12345,age*37计算得54321,相加的66666.
再添加元素计算name.hashCode()计算得54321,age*37计算得12345,相加也是得66666,
它们的返回值都是相同的,但是两个name和age是不同的,这就需要再次使用equals()判断
回复 使用道具 举报
本帖最后由 张文彬 于 2013-2-25 14:52 编辑

其实这是根据HashSet的取值规律的,实际上当程序向HashSet集合中添加元素时,HashSet会根据该元素的hashCode值来计算他的存储位置,也就是说,每个元素的hashCode值就可以决定他的存储“索引”(HashSet本身没有索引)
  1. //类A的equals方法总是返回true,但没有重写其hashCode()方法
  2. class A
  3. {
  4.         public boolean equals(Object obj)
  5.         {
  6.                 return true;
  7.         }
  8. }

  9.         //类B的hashCode()方法总是返回2,且有重写其equals()方法
  10. class B
  11. {
  12.         public int hashCode()
  13.         {
  14.                 return 2;
  15.         }
  16.         public boolean equals(Object obj)
  17.         {
  18.                 return true;
  19.         }
  20. }
  21. public class HashSetTest
  22. {
  23.         public static void main(String[] args)
  24.         {
  25.                 HashSet books = new HashSet();
  26.                 //分别向books集合中添加两个A对象,两个B对象
  27.                 books.add(new A());
  28.                 books.add(new A());
  29.                 books.add(new B());
  30.                 books.add(new B());
  31.                 System.out.println(books);
  32.         }
  33. }
复制代码
结果


这个例子就可以说明即使A对象通过equals()方法比较返回true,但HashSet依然把它们当成两个对象。
也就是说两个方法必须都重写。


回复 使用道具 举报
这个帖子 求加技术分啊   我都好久没加过了。。。。。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马