黑马程序员技术交流社区

标题: HashSet集合的小问题? [打印本页]

作者: 昝文萌    时间: 2013-10-28 17:41
标题: HashSet集合的小问题?
本帖最后由 昝文萌 于 2013-10-29 21:05 编辑

今天再练习老师代码时,发现一个不理解的问题?
  1. <p>ReflectPoint pt1 = new ReflectPoint(1,1);</p><p>  Collection collection = new HashSet();
  2. collection.add(pt1);</p><p>collection.add(pt1);//这里又添加一次pt1没有成功。</p><p> </p><p>//ReflectPiont类,里面重写了hashCode()和equals()方法</p><p>public class ReflectPoint {
  3. public int x;
  4. public int y;
  5. public ReflectPoint(int x, int y) {
  6.   super();
  7.   this.x = x;
  8.   this.y = y;
  9. }

  10. public int hashCode(){
  11.   System.out.println("hashcode");
  12.   return 1;
  13. }
  14. </p><p>//这个equals()方法永远返回false,按理说同样的元素应该能再次添加的
  15.     public boolean equals(Object obj){
  16.      return false;
  17.     }
  18. } </p>
复制代码
求大神指点一下?


作者: 亲雨泽    时间: 2013-10-28 18:01
概述:
Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。
      |--HashSet:底层数据结构是哈希表。线程不同步
           HashSet是如何保证元素的唯一性的呢?
           是通过元素的两个方法,hashCode和equals来完成。
           如果元素的HashCode值相同,才会判断equals是否为true。
           如果元素的HashCode不同。就不会调用equals方法。
  注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
作者: wenbaoxing    时间: 2013-10-28 19:24
请看我修改的代码:
  1. import java.util.*;

  2. class  HashSetQue
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                
  7.                 //ReflectPoint pt1 = new ReflectPoint(1,1);
  8.                 Collection collection = new HashSet();

  9.                 //这样才可以,你那样写代码,相等于是一个对象
  10.                 collection.add(new ReflectPoint(1,1));
  11.                 collection.add(new ReflectPoint(1,1));
  12.                 //collection.add(pt1);//这里又添加一次pt1没有成功。 //ReflectPiont类,里面重写了hashCode()和equals()方法

  13.                 System.out.println(collection);
  14.                
  15.         }
  16. }

  17. class ReflectPoint {
  18.         public int x;
  19.         public int y;

  20.         public ReflectPoint(int x, int y) {
  21.                 super();
  22.                 this.x = x;
  23.                 this.y = y;
  24.         }

  25.         public int hashCode(){
  26.                  System.out.println("hashcode");
  27.                  return 1;
  28.         }

  29.         //这个equals()方法永远返回false,按理说同样的元素应该能再次添加的
  30.     public boolean equals(Object obj){
  31.                 return false;
  32.     }

  33.         public String toString(){
  34.                 return "("+x+","+y+")";               
  35.         }
  36. }
复制代码

作者: 昝文萌    时间: 2013-10-28 20:22
wenbaoxing 发表于 2013-10-28 19:24
请看我修改的代码:

恩,如果是两个对象的话可以添加,但是HashSet集合判断对象是否是同一个的对象的依据就是hashCode()的返回值,和equals()的返回值,(第一个语句)collention.add(pt1),如果又执行一次(第二个语句)collention.add(pt1),这时就会算出第二个语句的pt1的hashCode()值,发现和第一个语句的pt1的hashCode()的值相等,然后又调用第二个语句的pt1的equals方法,结果是false,按这样的分析应该能继续存pt1的。
作者: wenbaoxing    时间: 2013-10-28 21:56
昝文萌 发表于 2013-10-28 20:22
恩,如果是两个对象的话可以添加,但是HashSet集合判断对象是否是同一个的对象的依据就是hashCode()的返 ...

看看源码把,我猜想,是不是先比较了地址值了
作者: 那得好好想想    时间: 2013-10-29 09:58
你还是没搞清楚set的基本原理。List与Set很像,它们都是单列元素的集合,所以,它们有一个功共同的父接口,叫Collection。不过Set里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。
简单一句话来说,list能重复,因为他是有序的,set不能重复。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2