,HashSet:数据结构是哈希表,线程是非同步的
哈希表是按照哈希值来存储的
不是同一对象,但是地址值是一样的,这个时候他会在该地址值下顺延。
保证元素唯一性的原理:判断元素的hashCode值是否相同
如果相同,还会继续判断元素的equals方法,是否为true;添加失败就为假。
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断euqals是否为true,如果元素的hashscode值不同,不会调用equals.(建立一个比较有针对性的hashcode会比较高效一些)- import java.util.HashSet;
- import java.util.Iterator;
- /**
- * HashSet存储自定义对象
- *
- * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
- */
- public class Test2 {
- public static void main(String[] args) {
- HashSet hs = new HashSet();
- hs.add(new Person("a1", 11));
- hs.add(new Person("a2", 12));
- hs.add(new Person("a3", 13));
- hs.add(new Person("a2", 12));
- //hs.add(new Person("a4", 14));
- Iterator it = hs.iterator();
- while (it.hasNext()) {
- Person p = (Person) it.next();
- sop(p.getName()+"::"+p.getAge());
- }
- }
- public static void sop(Object obj) {
- System.out.println(obj);
- }
- }
- class Person {
- private String name;
- public String getName() {
- return name;
- }
- public int getAge() {
- return age;
- }
- private int age;
- Person(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public boolean equals(Object obj) {
- if (!(obj instanceof Person)) {
- return false;
- }
- Person p = (Person) obj;
- return this.name.equals(p.name) && this.age == p.age;
- }
- }
复制代码 以上打印结果为:
a2::12
a1::11
a2::12
a3::13
equals没有被调用。因为比较先看地址。new 出来的,都有自己独立的hashcode,有自己的位置存储,都存进去了,不用再读equals方法了。
现在要覆盖Person 的hashcode方法,建立Person对象自己的哈希值。怎么建立哈希值呢?你的判断条件是什么,依据条件来生成哈希值,这里按照姓名年龄判断是不是同一个元素,那就依据这个条件判断哈希值。- import java.util.HashSet;
- import java.util.Iterator;
- /**
- * HashSet存储自定义对象
- *
- * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
- */
- public class Test2 {
- public static void main(String[] args) {
- HashSet hs = new HashSet();
- hs.add(new Person("a1", 11));
- hs.add(new Person("a2", 12));
- hs.add(new Person("a3", 13));
- hs.add(new Person("a2", 12));
- //hs.add(new Person("a4", 14));
- Iterator it = hs.iterator();
- while (it.hasNext()) {
- Person p = (Person) it.next();
- sop(p.getName()+"::"+p.getAge());
- }
- }
- public static void sop(Object obj) {
- System.out.println(obj);
- }
- }
- class Person {
- private String name;
- public String getName() {
- return name;
- }
- public int getAge() {
- return age;
- }
- private int age;
- Person(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public int hashCode(){
- System.out.println(this.name+"....hashcode");
- //按照条件设置hashcode
- return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一
- //不科学的比较方式 return 60;
- }
- public boolean equals(Object obj) {
- if (!(obj instanceof Person)) {
- return false;
- }
- Person p = (Person) obj;
- System.out.println(this.name+".euqals.."+p.name);
- return this.name.equals(p.name) && this.age == p.age;
- }
- }
复制代码 非科学打印结果为
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.- import java.util.HashSet;
- import java.util.Iterator;
- /**
- * HashSet存储自定义对象
- *
- * @author Administrator 网hashset存入自定义对象,姓名和年龄相同为同一个人,重复元素
- */
- public class Test2 {
- public static void main(String[] args) {
- HashSet hs = new HashSet();
- hs.add(new Person("a1", 11));
- hs.add(new Person("a2", 12));
- hs.add(new Person("a3", 13));
- hs.add(new Person("a2", 12));
- //hs.add(new Person("a4", 14));
- sop(hs.contains(new Person("a1",11)));
- hs.remove(new Person("a1",11));
- Iterator it = hs.iterator();
- while (it.hasNext()) {
- Person p = (Person) it.next();
- sop(p.getName()+"::"+p.getAge());
- }
- }
- public static void sop(Object obj) {
- System.out.println(obj);
- }
- }
- class Person {
- private String name;
- public String getName() {
- return name;
- }
- public int getAge() {
- return age;
- }
- private int age;
- Person(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public int hashCode(){
- System.out.println(this.name+"....hashcode");
- //按照条件设置hashcode
- return name.hashCode()+this.age*39;//39没有特殊意思,也可以是其他,容易导致hashcode相同,尽量保持哈希值的唯一
- //不科学的比较方式 return 60;
- }
- public boolean equals(Object obj) {
- if (!(obj instanceof Person)) {
- return false;
- }
- Person p = (Person) obj;
- System.out.println(this.name+".euqals.."+p.name);
- return this.name.equals(p.name) && this.age == p.age;
- }
- }
复制代码 ArrayList判断元素是否存在,和删除元素只依赖于equals,而hashSet依赖于hashCode和equals
|
|