黑马程序员技术交流社区

标题: hashset里的疑问 [打印本页]

作者: 歌诗王道    时间: 2014-4-10 14:56
标题: hashset里的疑问
本帖最后由 歌诗王道 于 2014-4-12 13:26 编辑

hashSet里的元素都是无序的,不允许重复,为什么在hashSet里添加字符串可以直接去重,添加对象时却还要复写hashCode方法和equals方法?
  1. class HashSetDmeo
  2. {
  3.     pubic static void sop(Object obj)
  4.      {
  5.           System.out.println(obj);  
  6.       }
  7.      
  8.     public static void main(String[] args)
  9.     {
  10.          HashSet hs = new HashSet();
  11.          hs.add("tom");
  12.          hs.add("jerry");
  13.          hs.add("marry");
  14.          hs.add("tom");
  15.          Iterator it = hs.iterator();
  16.          while(it.hasNext())
  17.          {
  18.             sop(it.next());
  19.           }

  20.          HashSet hs2 = new HashSet();
  21.          hs2.add("new Person("tom"));
  22.          hs2.add("new Person("jerry"));
  23.          hs2.add("new Person("marry"));
  24.          hs2.add("new Person("tom"));
  25.          Iterator it2 = hs2.iterator();
  26.          while(it2.hasNext())
  27.          {
  28.             Person p = (Person)it.next;
  29.             sop(p.getName());
  30.           }
  31.      }
  32.      
  33. }
  34. class Person
  35. {
  36.     private String name;
  37.     Person(String name)
  38.     {
  39.          this.name = name;
  40.      }
  41.     public String getName()
  42.     {
  43.          return name;
  44.      }
  45.    
  46.     public static int hashCode()
  47.     {
  48.          return 60;
  49.      }
  50.     public boolean equals(Object obj)
  51.     {
  52.          if(!(obj instanceof Person))
  53.               return false;
  54.          Person p = (Person)obj;
  55.          return this.name.equals(p.name);
  56.      }
  57.    
  58. }
复制代码




作者: _Water    时间: 2014-4-10 15:26
对于 HashSet 而言,它是基于 HashMap 实现的,HashSet 底层采用 HashMap 来保存所有元素,HashSet可以调用其内部的hashCode方法和equals方法实现在hashSet里添加字符串可以直接去重。
但是你要比较两个自定义的对象Person是不是相同,除了比较名字字符串以外,还需要看一个人的年龄是不是一样。如果不复写原来的比较方法,就不能确定年龄是不是一样,所以就需要重写覆盖原来的hashCode方法和equals方法。
作者: ﹊佑雨时杰↘    时间: 2014-4-10 15:41
HashSet: 内部数据结构是哈希表 ,是不同步的。
                如何保证该集合的元素唯一性呢?
                是通过对象的hashCode和equals方法来完成对象唯一性的。
                如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
                如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
                如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
               
                记住:如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
                一般情况下,如果定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals,hashCode方法。
                建立对象判断是否相同的依据。
作者: ﹊佑雨时杰↘    时间: 2014-4-10 15:43
﹊佑雨时杰↘ 发表于 2014-4-10 15:41
HashSet: 内部数据结构是哈希表 ,是不同步的。
                如何保证该集合的元素唯一性呢?
                是通过对象的hashCode ...

忘了说了 , String 里面已经把hashCode方法和equals方法  实现了。  所以你可以直接加,而自己写的类通常都需要覆盖equals,hashCode方法。
作者: jingdou56    时间: 2014-4-10 15:46
因为 HashSet 判断集合中的元素是否唯一,

通过 hashcode 和 equals这两个方法来实现的!

当你添加字符串元素时,相当于 String 类对象,他自己已经具备这两个方法了,

所以它就可以保证字符串的唯一,可以去重;

但是当元素为自定义类型时,如果你不复习 hashcode和equals方法,

它就没法来判断元素的唯一性,就可能导致元素重复!

而且复写可以让它按照你的规则来排序!




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