黑马程序员技术交流社区
标题: set集合框架的一点疑问 [打印本页]
作者: x378320002 时间: 2013-5-24 10:46
标题: set集合框架的一点疑问
本帖最后由 x378320002 于 2013-5-24 14:17 编辑
代码如下:- public static void main(String[] args) {
- HashSet hs = new HashSet();
- /*
- * HashSet集合数据结构是哈希表,所以存储元素的时候,
- * 使用的元素的hashCode方法来确定位置,如果位置相同,在通过元素的equals来确定是否相同
- */
- hs.add("java");
复制代码 添加元素时会调用2个方法,public int hashCode() 和equals();不清楚这个调用是谁调用的啊?
是新添加进来的元素调用方法和别的比呢,还是本来的元素调用了方法和新进的比,就如我添加java元素
到hashset中,this指谁?obj指谁呢?- public boolean equals(Object obj) {
- if(this == obj)
- return true;
复制代码
作者: 孙金鑫 时间: 2013-5-24 11:03
HashSet本身实现了Set接口,本身就调用的hashCode()和equals()方法,所以我们需要通常复写两个方法,确保他们的值是否一样。
“到hashset中,this指谁?obj指谁呢?”………………这里的this,是代表本类对象,obj是你传进来的对象,所以本类对象和另外一个对象做比较。。。
作者: 金辉 时间: 2013-5-24 11:07
this代表的是一个对象。哪个对象调用this所在的函数,this就代表哪个对象
obj是你调用equals方法时传入的参数,也就是要比较的对象
作者: Super_Class 时间: 2013-5-24 12:32
Set集合中的元素不允许重复
hs.add("java");//这里还没有进行比较。因为一开始Set集合中的元素是空的。
如果再加上这么一句:
hs.add("world");//这里就会开始比较了。
|----哈希表确定元素是否相同
1、 判断的是两个元素的哈希值是否相同
如果相同,再判断两个对象的内容是否相同
2. 判断哈希值相同,其实判断的是对象的hashCode方法。判断内容相同用的是equals方法
作者: student 时间: 2013-5-24 15:31
本帖最后由 student 于 2013-5-24 15:55 编辑
解答一:简而言之,就是Set集合中添加什么对象,什么对象就调用hashCode和equals方法。
以你的代码为例:
向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集合中其他对象。
作者: x378320002 时间: 2013-5-24 17:58
student 发表于 2013-5-24 15:31
解答一:简而言之,就是Set集合中添加什么对象,什么对象就调用hashCode和equals方法。
以你的代码为例:
...
这个不对吧?
作者: student 时间: 2013-5-24 18:41
x378320002 发表于 2013-5-24 17:58
这个不对吧?
为了验证对不对,我写个小程序:定义一个Person类,该类中有一个成员变量name。
在Person类中覆盖equals方法和hashCode方法。为简便,这里的equals和hashCode方法只是输出内容,不做具体的计算。
代码如下,通过运行结果可知,向Set集合中添加Person对象时,是Person对象调用equals和hashCode方法:- import java.util.HashSet;
- class Person {
- private String name;
- public Person(String name) {
- this.name = name;
- }
- @Override
- public int hashCode() {
- System.out.println("调用hashCode方法");
- return 10;
- }
- @Override
- public boolean equals(Object obj) {
- System.out.println("调用 equals方法");
- return true;
- }
-
- }
- public class HashSetTest {
- public static void main(String[] args) {
- Person p1 = new Person("java");
- Person p2 = new Person("Student");
- HashSet<Person> set = new HashSet<Person>();
- set.add(p1);
- set.add(p2);
- /*
- * 运行结果:
- * 调用hashCode方法
- * 调用hashCode方法
- * 调用 equals方法
- */
- }
- }
复制代码
作者: x378320002 时间: 2013-5-24 19:30
student 发表于 2013-5-24 18:41
为了验证对不对,我写个小程序:定义一个Person类,该类中有一个成员变量name。
在Person类中覆盖equals ...
如果这样,也就是this>obj时 就是返回正数时,代表传进来的比已经有的大,返回负数时代表传进的比已有的小啦.
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |