国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > php教程 > Java---27---Set集合及其子类HashSet

Java---27---Set集合及其子类HashSet

来源:程序员人生   发布时间:2015-04-17 09:06:05 阅读次数:3770次

Set中元素是无序的(存入和取出的顺序不1定1致),元素不可以重复。

 

Set中的方法和Collection中的方法是1样的。

常见子类:HashSet  TreeSet

HashSet 底层数据结构是哈希表

TreeSet 底层数据结构是2叉树


import java.util.HashSet; import java.util.Iterator; class Person{ private String name; private int age; public Person(String name, int age) { super(); this.name = name; this.age = age; } //set and get methods public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class SetDemo { public static void main(String[] args) { // TODO Auto-generated method stub //method1(); method2(); } public static void method1() { HashSet hs = new HashSet(); hs.add("01"); hs.add("02"); hs.add("03"); hs.add("04"); // 无序性 sop(hs); hs.add("02"); // 唯1性 sop(hs); sop("是不是添加进去:" + hs.add("02")); } /** * 存入自定义对象,如果姓名和年龄相同视为同1个人,重复元素 */ public static void method2 (){ HashSet hs = new HashSet(); hs.add(new Person("01",10)); hs.add(new Person("02",11)); hs.add(new Person("03",12)); hs.add(new Person("04",13)); /*打印 Iterator it = hs.iterator(); while (it.hasNext()){ Person person = (Person)it.next(); sop(person.getName()+"::"+person.getAge()); } */ //添加1个相同元素 hs.add(new Person("01", 10)); Iterator it = hs.iterator(); while (it.hasNext()){ Person person = (Person)it.next(); sop(person.getName()+"::"+person.getAge()); } //没解决啊。。。两个01::10 } public static void sop(Object object) { System.out.println(object); } }


我们要求 姓名和年龄相同视为是重复元素,依照Set的特性来讲是不应当被保存的,结果却是存上了。。。

 

解决:覆盖元素的hashCode 方法,建立自己的哈希值,同时覆盖equals方法。

 

覆盖元素HashCode方法 是由于,在Set中存入元素,首先被判断的就是元素的哈希值,只有当元素的哈希值没有出现过的时候,才会将元素存入。

覆盖equals方法是由于,两个元素的哈希值相同,但是这两个元素不1定是相同的,因此来判断1下,并根据返回值来决定该元素终究能否被存入。



package ssssssss; import java.util.HashSet; import java.util.Iterator; class Person { private String name; private int age; public Person(String name, int age) { super(); this.name = name; this.age = age; } public boolean equals(Object obj) { // TODO Auto-generated method stub if (!(obj instanceof Person)) return false; Person person = (Person) obj; //打印 表示此方法被调用 System.out.println(this.name + "******equals*****" + person.name); return this.name.equals(person.name) && this.age == person.age; } //覆盖hashCode方法 建立Person自己的哈希值 public int hashCode() { // TODO Auto-generated method stub System.out.println(this.name + "..........hashCode"); return 13; //依照条件设定哈希值 //return name.hashCode() + age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class SetDemo { public static void main(String[] args) { // TODO Auto-generated method stub method2(); } /** * 存入自定义对象,如果姓名和年龄相同视为同1个人,重复元素 */ public static void method2 (){ HashSet hs = new HashSet(); hs.add(new Person("01",10)); hs.add(new Person("02",11)); hs.add(new Person("03",12)); hs.add(new Person("04",13)); /*打印 Iterator it = hs.iterator(); while (it.hasNext()){ Person person = (Person)it.next(); sop(person.getName()+"::"+person.getAge()); } */ //添加1个相同元素 hs.add(new Person("01", 10)); Iterator it = hs.iterator(); while (it.hasNext()){ Person person = (Person)it.next(); sop(person.getName()+"::"+person.getAge()); } //没解决啊。。。两个01::10 //覆盖 hashcode方法,建立自己的哈希值 } public static void sop(Object object) { System.out.println(object); } }

打印结果:

01..........hashCode 02..........hashCode 02******equals*****01 03..........hashCode 03******equals*****01 03******equals*****02 04..........hashCode 04******equals*****01 04******equals*****02 04******equals*****03 01..........hashCode 01******equals*****01 01::10 02::11 03::12 04::13


返回1个相同的哈希值,通过打印结果我们不难猜出此程序的运行进程:

01先生成1个哈希值,由于此时就只有011个元素,所以存入

02再生成1个相同的哈希值,然后跟01比较,不是同1元素,存入

03再生成相同的哈希值,然后跟01和02进行比较,肯定没有相同元素,存入

04也是1样,跟01 02 03比较完后,存入

接着就是重复元素01了,比较发现跟第1次存入的01是相同的,

返回false,没有存入。

 

结论:

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

通过元素的两个方法:hashCode和equals

只有当元素的哈希值相等的时候才会判断equals方法

 

那如果生成不同的哈希值的话,就能够大大的减少程序的运行次数。


package ssssssss; import java.util.HashSet; import java.util.Iterator; class Person { private String name; private int age; public Person(String name, int age) { super(); this.name = name; this.age = age; } public boolean equals(Object obj) { // TODO Auto-generated method stub if (!(obj instanceof Person)) return false; Person person = (Person) obj; //打印 表示此方法被调用 System.out.println(this.name + "******equals*****" + person.name); return this.name.equals(person.name) && this.age == person.age; } //覆盖hashCode方法 建立Person自己的哈希值 public int hashCode() { // TODO Auto-generated method stub System.out.println(this.name + "..........hashCode"); //return 13; //依照条件设定哈希值 return name.hashCode() + age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class SetDemo { public static void main(String[] args) { // TODO Auto-generated method stub method2(); } /** * 存入自定义对象,如果姓名和年龄相同视为同1个人,重复元素 */ public static void method2 (){ HashSet hs = new HashSet(); hs.add(new Person("01",10)); hs.add(new Person("02",11)); hs.add(new Person("03",12)); hs.add(new Person("04",13)); /*打印 Iterator it = hs.iterator(); while (it.hasNext()){ Person person = (Person)it.next(); sop(person.getName()+"::"+person.getAge()); } */ //添加1个相同元素 hs.add(new Person("01", 10)); Iterator it = hs.iterator(); while (it.hasNext()){ Person person = (Person)it.next(); sop(person.getName()+"::"+person.getAge()); } //没解决啊。。。两个01::10 //覆盖 hashcode方法,建立自己的哈希值 } public static void sop(Object object) { System.out.println(object); } }



生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生