1 package JiHe.Set;
2 import java.util.HashSet;
3 import java.util.Iterator;
4 /*
5 * Set :元素是无序(存放和取出的顺序不一定一致),元素不可以重复;
6 * |--HashSet:底层数据结构是哈希表(注意:如果想要保证自定义对象的唯一性,一般需要复写hashCode方法和equale方法)
7 * 保证唯一性的原理:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的equals返回来的是否为true
8 * |--TreeSet:
9 */
10 public class MyHashSet {
11 public static void main(String[] args) {
12 // myHashSet();
13 mapleZhiDingYi();
14 }
15
16 //此方法演示HashSet如何取出数据
17 public static void myHashSet(){
18 HashSet hs = new HashSet();
19 //添加数据,返回boolean类型的值,如果元素被存放进去了,就返回true,因为该集合是不能重复的,所以如果存放相同的数据进去,返回false
20 hs.add("java1");
21 hs.add("java2");
22 hs.add("java3");
23 hs.add("java4");
24
25 //取出数据,注意;hashSet集合取出数据只能使用迭代器
26 Iterator it = hs.iterator();
27 while(it.hasNext()){
28 System.out.println(it.next()); //输出来的是无序的
29 }
30 }
31
32
33 //存储自定义对象,姓名和年龄如果相同为同一个人,重复元素
34 public static void mapleZhiDingYi(){
35 //创建一个HashSet集合,每个集合里面添加一个Person对象
36 HashSet hs = new HashSet();
37
38 /*
39 * HashSet集合是如何保证元素的唯一性呢?
40 * 在添加自定义对象的时候,创建对象,程序会自动算出该对象的hashCode值,然后存放到内在中,
41 * 如果内存中已经拥有hashCode值相同的元素,则调用Person类中复写的equals方法,对Person类的名称和年龄进行比较
42 * 根据比较的结果返回一个boolean的值,来判断该元素是否是重复元素,如果是,则删掉,如果不是,则存放到集合中
43 * (注意:如果两个对象的hashCode值相等,会依次和每一个对象进行比较,比较的是其中的名称和年龄值)
44 * (注意:当hashCode值相等时,才会调用equals方法去比较,如果不重复,则不会调用equals方法)
45 * */
46 hs.add(new Person("a1",11));
47 hs.add(new Person("a2",22));
48 hs.add(new Person("a3",33));
49 hs.add(new Person("a4",44));
50 hs.add(new Person("a4",44));
51
52 Iterator it = hs.iterator();
53 while(it.hasNext()){
54 //定义一个Person类型的对象,用来存储当前获取到的对象,并且调用里面的值
55 Person p = (Person)it.next();
56 System.out.println(p.getName()+"..."+p.getAge());
57 }
58 }
59 }
60
61
62 /*
63 * 定义一个人类,该类拥有name和age属性
64 */
65 class Person{
66 private String name;
67 private int age;
68
69 Person(String name, int age){
70 this.name = name;
71 this.age = age;
72 }
73
74 public String getName(){
75 return name;
76 }
77
78 public int getAge(){
79 return age;
80 }
81
82 //注意该方法的名称;是HashSet集合中的hashCode方法,而不是Object中的hasCode方法
83 public int hashCode(){
84 // return 50;
85
86 //因为name值是字符串,所以每个字符串都有自己的hashCode方法,将生成出来的hashCode和年龄相加,做为hashCode值返回
87 return name.hashCode()+age; //这种写法比较灵活,生成出来的hashCode一般都不会重复,这样做尽量保证了hashCode的唯一性
88 }
89
90 /*
91 * 首先判断用户传入的对象是不是Person对象
92 * 再将用户强转为Person对象,对当前对象和传入对象的名称和年龄进行比较,将比较结果返回
93 */
94 public boolean equals(Object obj){
95 if(!(obj instanceof Person)){
96 return false;
97 }
98
99 Person p = (Person)obj;
100 //将用户传递过来的对象的姓名和年龄和当前对象的姓名和年龄进行比较,将比较的结果返回
101 return this.name.equals(p.name) && this.age == p.age;
102 }
103 }