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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© x378320002 中级黑马   /  2013-5-24 10:46  /  1928 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 x378320002 于 2013-5-24 14:17 编辑

代码如下:
  1. public static void main(String[] args) {
  2.                 HashSet hs = new HashSet();
  3.                 /*
  4.                  * HashSet集合数据结构是哈希表,所以存储元素的时候,
  5.                  * 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同
  6.                  */
  7.                 hs.add("java");
复制代码
添加元素时会调用2个方法,public int hashCode() 和equals();不清楚这个调用是谁调用的啊?
是新添加进来的元素调用方法和别的比呢,还是本来的元素调用了方法和新进的比,就如我添加java元素
到hashset中,this指谁?obj指谁呢?
  1. public boolean equals(Object obj) {
  2.                 if(this == obj)
  3.                         return true;
复制代码

7 个回复

倒序浏览
HashSet本身实现了Set接口,本身就调用的hashCode()和equals()方法,所以我们需要通常复写两个方法,确保他们的值是否一样。

“到hashset中,this指谁?obj指谁呢?”………………这里的this,是代表本类对象,obj是你传进来的对象,所以本类对象和另外一个对象做比较。。。
回复 使用道具 举报
this代表的是一个对象。哪个对象调用this所在的函数,this就代表哪个对象
obj是你调用equals方法时传入的参数,也就是要比较的对象
回复 使用道具 举报

Set集合中的元素不允许重复
hs.add("java");//这里还没有进行比较。因为一开始Set集合中的元素是空的。

如果再加上这么一句:

hs.add("world");//这里就会开始比较了。

|----哈希表确定元素是否相同
                                                        1、 判断的是两个元素的哈希值是否相同
                                                                如果相同,再判断两个对象的内容是否相同
                                                        2. 判断哈希值相同,其实判断的是对象的hashCode方法。判断内容相同用的是equals方法
回复 使用道具 举报
本帖最后由 student 于 2013-5-24 15:55 编辑

解答一:简而言之,就是Set集合中添加什么对象,什么对象就调用hashCode和equals方法。
以你的代码为例:

  1. hs.add("java")
复制代码
向Set集合中添加String类型的对象,所以调用hashCode和equals方法的就是String对象。

这两个方法调用的顺序和规则是:先调用hashCode方法计算每一个元素的哈希值,如果集合中有一个元素哈希值和另一个元素相同,
才再调用equals方法,如果不同则不会调用equals方法,详细分析如下:

      1.当添加第一个元素"java"时,调用hashCode方法计算该元素的哈希值,第一次不会调用equals方法;
      2.如果再次向Set集合中添加元素"java",调用hashCode方法获得该元素的哈希值,发现哈希值和上面元素相同,
然后调用equals方法和集合中
所有元素进行比较,发现"java"对象和Set集合中的对象相等,所以阻止
第二个"java"对象添加到Set集合中,保证元素唯一性;
      3.当添加"Student"时,首先用hashCode方法计算哈希值,发现哈希值和Set集合中所有元素的哈希值不同,不再调用equals方法,并将"Student"添加

到Set集合中   
这就是Set集合保证元素唯一性的机制,即首先调用hashCode,再调用equals方法。

解答二:在equals方法中,this指谁?obj指谁呢?
我们知道,this指的是当前对象的引用,所以当向Set集合中添加"java"这个对象时,this指的是"java"对象,
obj指的是Set集合中其他对象。


回复 使用道具 举报
student 发表于 2013-5-24 15:31
解答一:简而言之,就是Set集合中添加什么对象,什么对象就调用hashCode和equals方法。
以你的代码为例:
...

这个不对吧?
回复 使用道具 举报
x378320002 发表于 2013-5-24 17:58
这个不对吧?

为了验证对不对,我写个小程序:定义一个Person类,该类中有一个成员变量name。

在Person类中覆盖equals方法和hashCode方法。为简便,这里的equals和hashCode方法只是输出内容,不做具体的计算。
代码如下,通过运行结果可知,向Set集合中添加Person对象时,是Person对象调用equals和hashCode方法:
  1. import java.util.HashSet;

  2. class Person {
  3.     private String name;

  4.     public Person(String name) {
  5.         this.name = name;
  6.     }

  7.     @Override
  8.     public int hashCode() {
  9.         System.out.println("调用hashCode方法");
  10.         return 10;
  11.     }

  12.     @Override
  13.     public boolean equals(Object obj) {
  14.         System.out.println("调用 equals方法");
  15.         return true;
  16.     }
  17.    
  18. }

  19. public class HashSetTest {

  20.     public static void main(String[] args) {

  21.         Person p1 = new Person("java");
  22.         Person p2 = new Person("Student");
  23.         HashSet<Person> set = new HashSet<Person>();
  24.         set.add(p1);
  25.         set.add(p2);
  26.         /*
  27.          *     运行结果:
  28.          *     调用hashCode方法
  29.          *     调用hashCode方法
  30.          *     调用 equals方法
  31.          */
  32.     }
  33. }
复制代码
回复 使用道具 举报
student 发表于 2013-5-24 18:41
为了验证对不对,我写个小程序:定义一个Person类,该类中有一个成员变量name。

在Person类中覆盖equals ...

如果这样,也就是this>obj时 就是返回正数时,代表传进来的比已经有的大,返回负数时代表传进的比已有的小啦.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马