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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© gzbbxu 中级黑马   /  2013-6-27 16:48  /  1071 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

,HashSet:数据结构是哈希表,线程是非同步的

         哈希表是按照哈希值来存储的

          不是同一对象,但是地址值是一样的,这个时候他会在该地址值下顺延。

            保证元素唯一性的原理:判断元素的hashCode值是否相同

           如果相同,还会继续判断元素的equals方法,是否为true;添加失败就为假。

            HashSet是如何保证元素唯一性的呢?

              是通过元素的两个方法,hashCode和equals来完成。

              如果元素的HashCode值相同,才会判断euqals是否为true,如果元素的hashscode值不同,不会调用equals.(建立一个比较有针对性的hashcode会比较高效一些)
  1. import java.util.HashSet;
  2. import java.util.Iterator;

  3. /**
  4. * HashSet存储自定义对象
  5. *
  6. * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
  7. */
  8. public class Test2 {
  9.         public static void main(String[] args) {
  10.                 HashSet hs = new HashSet();
  11.                 hs.add(new Person("a1", 11));
  12.                 hs.add(new Person("a2", 12));
  13.                 hs.add(new Person("a3", 13));
  14.                 hs.add(new Person("a2", 12));
  15.                 //hs.add(new Person("a4", 14));
  16.                 Iterator it = hs.iterator();
  17.                 while (it.hasNext()) {
  18.                         Person p = (Person) it.next();
  19.                         sop(p.getName()+"::"+p.getAge());
  20.                 }
  21.         }

  22.         public static void sop(Object obj) {
  23.                 System.out.println(obj);
  24.         }
  25. }

  26. class Person {
  27.         private String name;

  28.         public String getName() {
  29.                 return name;
  30.         }

  31.         public int getAge() {
  32.                 return age;
  33.         }

  34.         private int age;

  35.         Person(String name, int age) {
  36.                 this.name = name;
  37.                 this.age = age;
  38.         }

  39.         public boolean equals(Object obj) {
  40.                 if (!(obj instanceof Person)) {
  41.                         return false;
  42.                 }
  43.                 Person p = (Person) obj;
  44.                 return this.name.equals(p.name) && this.age == p.age;
  45.         }
  46. }
复制代码
以上打印结果为:

     a2::12
     a1::11
     a2::12   
     a3::13

equals没有被调用。因为比较先看地址。new 出来的,都有自己独立的hashcode,有自己的位置存储,都存进去了,不用再读equals方法了。

现在要覆盖Person 的hashcode方法,建立Person对象自己的哈希值。怎么建立哈希值呢?你的判断条件是什么,依据条件来生成哈希值,这里按照姓名年龄判断是不是同一个元素,那就依据这个条件判断哈希值。
  1. import java.util.HashSet;
  2. import java.util.Iterator;

  3. /**
  4. * HashSet存储自定义对象
  5. *
  6. * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
  7. */
  8. public class Test2 {
  9.         public static void main(String[] args) {
  10.                 HashSet hs = new HashSet();
  11.                 hs.add(new Person("a1", 11));
  12.                 hs.add(new Person("a2", 12));
  13.                 hs.add(new Person("a3", 13));
  14.                 hs.add(new Person("a2", 12));
  15.                 //hs.add(new Person("a4", 14));
  16.                 Iterator it = hs.iterator();
  17.                 while (it.hasNext()) {
  18.                         Person p = (Person) it.next();
  19.                         sop(p.getName()+"::"+p.getAge());
  20.                 }
  21.         }

  22.         public static void sop(Object obj) {
  23.                 System.out.println(obj);
  24.         }
  25. }

  26. class Person {
  27.         private String name;

  28.         public String getName() {
  29.                 return name;
  30.         }

  31.         public int getAge() {
  32.                 return age;
  33.         }

  34.         private int age;

  35.         Person(String name, int age) {
  36.                 this.name = name;
  37.                 this.age = age;
  38.         }
  39.     public int hashCode(){
  40.             System.out.println(this.name+"....hashcode");
  41.             //按照条件设置hashcode
  42.             return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一
  43.     //不科学的比较方式        return 60;
  44.     }
  45.         public boolean equals(Object obj) {
  46.                 if (!(obj instanceof Person)) {
  47.                         return false;
  48.                 }
  49.                 Person p = (Person) obj;
  50.                 System.out.println(this.name+".euqals.."+p.name);
  51.                 return this.name.equals(p.name) && this.age == p.age;
  52.         }
  53. }
复制代码
非科学打印结果为

a1....hashcode
a2....hashcode
a2.euqals..a1
a3....hashcode
a3.euqals..a2
a3.euqals..a1
a2....hashcode
a2.euqals..a3
a2.euqals..a2
a3::13
a2::12
a1::11
HashSet判断和删除的依据

注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。先判断hashCode,hashcode如果有的话, 再判断equals.
  1. import java.util.HashSet;
  2. import java.util.Iterator;

  3. /**
  4. * HashSet存储自定义对象
  5. *
  6. * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
  7. */
  8. public class Test2 {
  9.         public static void main(String[] args) {
  10.                 HashSet hs = new HashSet();
  11.                 hs.add(new Person("a1", 11));
  12.                 hs.add(new Person("a2", 12));
  13.                 hs.add(new Person("a3", 13));
  14.                 hs.add(new Person("a2", 12));
  15.                 //hs.add(new Person("a4", 14));
  16.                 sop(hs.contains(new Person("a1",11)));
  17.                 hs.remove(new Person("a1",11));
  18.                 Iterator it = hs.iterator();
  19.                 while (it.hasNext()) {
  20.                         Person p = (Person) it.next();
  21.                         sop(p.getName()+"::"+p.getAge());
  22.                 }
  23.         }

  24.         public static void sop(Object obj) {
  25.                 System.out.println(obj);
  26.         }
  27. }

  28. class Person {
  29.         private String name;

  30.         public String getName() {
  31.                 return name;
  32.         }

  33.         public int getAge() {
  34.                 return age;
  35.         }

  36.         private int age;

  37.         Person(String name, int age) {
  38.                 this.name = name;
  39.                 this.age = age;
  40.         }
  41.     public int hashCode(){
  42.             System.out.println(this.name+"....hashcode");
  43.             //按照条件设置hashcode
  44.             return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一
  45.     //不科学的比较方式        return 60;
  46.     }
  47.         public boolean equals(Object obj) {
  48.                 if (!(obj instanceof Person)) {
  49.                         return false;
  50.                 }
  51.                 Person p = (Person) obj;
  52.                 System.out.println(this.name+".euqals.."+p.name);
  53.                 return this.name.equals(p.name) && this.age == p.age;
  54.         }
  55. }
复制代码
ArrayList判断元素是否存在,和删除元素只依赖于equals,而hashSet依赖于hashCode和equals


1 个回复

倒序浏览
连续听了两遍总算弄明白了,,求鼓励啊
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马