大数据之路week02 Collection 集合体系收尾(Set)

Posted Xiaohu_BigData

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大数据之路week02 Collection 集合体系收尾(Set)相关的知识,希望对你有一定的参考价值。

1、Set集合(理解)

  (1)Set集合的特点

    无序,唯一。

  (2)HashSet集合(掌握)

    A: 底层数据结构是哈希表(是一个元素为链表的数组)

    B: 哈希表底层依赖两个方法: hashCode() 和 equals()

      执行顺序:

        首先比较哈希值是否相同

          相同:继续执行equals()方法

            返回true:元素重复了,不添加

            返回false:直接把元素添加到集合

          不同:就直接把元素添加到集合

1、人的类

 1 package com.wyh.hashSet;
 2 
 3 /** 
 4 * @author WYH
 5 * @version 2019年11月17日 上午9:21:02
 6 */
 7 public class Person {
 8     private String name;
 9     private int age;
10     
11     public Person(String name, int age) {
12         super();
13         this.name = name;
14         this.age = age;
15     }
16     public Person() {
17         super();
18         // TODO Auto-generated constructor stub
19     }
20     
21     public String getName() {
22         return name;
23     }
24     public void setName(String name) {
25         this.name = name;
26     }
27     public int getAge() {
28         return age;
29     }
30     public void setAge(int age) {
31         this.age = age;
32     }
33     
34     //重写hashCode方法和equals方法
35     @Override
36     public int hashCode() {
37         final int prime = 31;
38         int result = 1;
39         result = prime * result + age;
40         result = prime * result + ((name == null) ? 0 : name.hashCode());
41         return result;
42     }
43     @Override
44     public boolean equals(Object obj) {
45         if (this == obj)
46             return true;
47         if (obj == null)
48             return false;
49         if (getClass() != obj.getClass())
50             return false;
51         Person other = (Person) obj;
52         if (age != other.age)
53             return false;
54         if (name == null) {
55             if (other.name != null)
56                 return false;
57         } else if (!name.equals(other.name))
58             return false;
59         return true;
60     }
61     
62 
63 }

2、测试类:

 1 package com.wyh.hashSet;
 2 
 3 import java.util.HashSet;
 4 
 5 /** 
 6 * @author WYH
 7 * @version 2019年11月17日 上午9:21:16
 8 */
 9 public class HashSetDemo01 {
10     public static void main(String[] args) {
11         //创建HashSet集合
12         HashSet<Person> hs = new HashSet<Person>();
13         
14         //创建Person类
15         Person p1 = new Person("小虎",22);
16         Person p2 = new Person("小强",23);
17         Person p3 = new Person("小虎",22);
18         Person p4 = new Person("小美",21);
19         Person p5 = new Person("小雪",21);
20         
21         //将对象添加到HashSet中去
22         hs.add(p1);
23         hs.add(p2);
24         hs.add(p3);
25         hs.add(p4);
26         hs.add(p5);
27         
28         
29         //遍历
30         for(Person p : hs) {
31             System.out.println(p.getName()+"---"+p.getAge());
32             
33             
34         }
35     }
36 
37 }

3、如下图,如果不重写hashCode()方法和equals()方法,运行结果,可以运行不报错,但是重复的元素也加入了。

4、重写后:

    C:如何保证元素的唯一性呢?

      由hashCode()和equals()保证的(如下图,流程)

 

 

 

    D:开发的时候,代码非常的简单,自动生成即可。

    E:HashSet存储字符串并遍历

 1 package com.wyh.set;
 2 
 3 import java.util.HashSet;
 4 
 5 /** 
 6 * @author WYH
 7 * @version 2019年11月16日 下午7:42:24
 8 * 
 9 * HashSet在存储字符串的时候,为什么只存储相同的字符串只存储一个呢?
10 * 通过查看add方法的源码,我们发现这个方法的底层方法是依赖两个方法,hashCode()和equals() 
11 * 
12 * 
13 */
14 public class HashSetDemo01 {
15     public static void main(String[] args) {
16         HashSet<String> hs = new HashSet<String>();
17         
18         hs.add("Hello");
19         hs.add("World");
20         hs.add("Java");
21         hs.add("World");
22         
23         for(String s : hs) {
24             System.out.println(s);
25         }
26     
27     }
28 
29 }

    F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)

  (3)TreeSet集合

    A:底层数据结构是红黑树(是一个自平衡的二叉树)

 

 

 

    B:  保证元素的排序方式

      a: 自然排序(元素具备比较性)

        让元素所属的类实现Comparable接口(难点,需求会给出主要条件,但是需要我们分析次要条件,例如 需求是根据年龄的长度进行排序,但是我们还要考虑姓名的长度和内容)

学生类:

 1 package com.wyh.treeSet;
 2 
 3 /** 
 4 * @author WYH
 5 * @version 2019年11月17日 上午11:13:45
 6 */
 7 public class Student2 implements Comparable<Student2>{
 8     private String name;
 9     private int age;
10     public Student2(String name, int age) {
11         super();
12         this.name = name;
13         this.age = age;
14     }
15     public Student2() {
16         super();
17         // TODO Auto-generated constructor stub
18     }
19     public String getName() {
20         return name;
21     }
22     public void setName(String name) {
23         this.name = name;
24     }
25     public int getAge() {
26         return age;
27     }
28     public void setAge(int age) {
29         this.age = age;
30     }
31     @Override
32     public int compareTo(Student2 s) {
33         int num = this.name.length() - s.name.length();
34         //次要条件1 姓名长度一样,内容不一定一样
35         int num2 = num == 0 ? (this.name.compareTo(s.name)) : num;
36         //次要条件2 姓名长度和内容一样,年龄不一定一样
37         int num3 = num2 == 0 ? this.age - s.age : num2;
38         return num3;
39         
40     }
41     
42     
43     
44     
45 }

测试类:

如果不重写自然排序方法,就会报错,因为没有给定如何排序,也没有保证唯一性
// java.lang.ClassCastException: com.wyh.treeSet.Student cannot be cast to
// java.lang.Comparable

 1 package com.wyh.treeSet;
 2 
 3 import java.util.TreeSet;
 4 
 5 /**
 6  * @author WYH
 7  * @version 2019年11月17日 下午2:27:13
 8  * 
 9  *          根据年龄的长度进行排序
10  */
11 public class TreeSetDemo03 {
12     public static void main(String[] args) {
13         TreeSet<Student2> ts = new TreeSet<Student2>();
14 
15         // 创建学生对象
16         Student2 s1 = new Student2("王友虎", 22);
17         Student2 s2 = new Student2("赵以浩", 24);
18         Student2 s3 = new Student2("齐博源", 21);
19         Student2 s4 = new Student2("李先锋", 23);
20         Student2 s5 = new Student2("李宏灿", 22);
21         Student2 s6 = new Student2("薛长城", 23);
22         Student2 s7 = new Student2("黄天祥", 24);
23         Student2 s8 = new Student2("王友虎", 23);
24 
25         // 添加到TreeSet中
26         ts.add(s1);
27         ts.add(s2);
28         ts.add(s3);
29         ts.add(s4);
30         ts.add(s5);
31         ts.add(s6);
32         ts.add(s7);
33         ts.add(s8);
34 
35         // 遍历
36         // 如果不重写自然排序方法,就会报错,因为没有给定如何排序,也没有保证唯一性
37         // java.lang.ClassCastException: com.wyh.treeSet.Student cannot be cast to
38         // java.lang.Comparable
39         for (Student2 s : ts) {
40             System.out.println(s.getName() + "---" + s.getAge());
41         }
42 
43     }
44 
45 

      b: 比较器排序(集合具备比较性)

        让集合构造方法接收Comparator的实现类对象(但是我们一般用匿名内部类的方式实现)

方式1、我们不用内部类的方式实现:

定义一个类实现Comparator<T> 接口,重写compare方法:

 1 package com.wyh.treeSet2;
 2 
 3 import java.util.Comparator;
 4 
 5 /** 
 6 * @author WYH
 7 * @version 2019年11月17日 下午2:48:22
 8 */
 9 public class MyComparator implements Comparator<Student2> {
10 
11     @Override
12     public int compare(Student2 s1, Student2 s2) {
13         int num = s1.getName().length() - s2.getName().length();
14         int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
15         int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
16         return num3;
17     }
18 
19     
20 
21 }

测试类:

 1 package com.wyh.treeSet2;
 2 
 3 import java.util.Comparator;
 4 import java.util.TreeSet;
 5 
 6 /**
 7  * @author WYH
 8  * @version 2019年11月17日 下午2:27:13
 9  * 
10  *          根据年龄的长度进行排序
11  */
12 public class TreeSetDemo03 {
13     public static void main(String[] args) {
14 //        TreeSet<Student2> ts = new TreeSet<Student2>();
15         TreeSet<Student2> ts = new TreeSet<Student2>(new MyComparator());
16         
17         //如果一个方法的参数是接口,那么真正要的是实现这个接口的实现类
18         //匿名内部类可以是实现
19        /* TreeSet<Student2> ts = new TreeSet<Student2>(new Comparator<Student2>(){
20             @Override
21             public int compare(Student2 s1, Student2 s2) {
22                 int num = s1.getName().length() - s2.getName().length();
23                 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
24                 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
25                 return num3;
26             }
27         });*/
28  
29         // 创建学生对象
30         Student2 s1 = new Student2("王友虎", 22);
31         Student2 s2 = new Student2("赵以浩", 24);
32         Student2 s3 = new Student2("齐博源", 21);
33         Student2 s4 = new Student2("李先锋", 23);
34         Student2 s5 = new Student2("李宏灿", 22);
35         Student2 s6 = new Student2("薛长城", 23);
36         Student2 s7 = new Student2("黄天祥", 24);
37         Student2 s8 = new Student2("王友虎", 23);
38 
39         // 添加到TreeSet中
40         ts.add(s1);
41         ts.add(s2);
42         ts.add(s3);
43         ts.add(s4);
44         ts.add(s5);
45         ts.add(s6);
46         ts.add(s7);
47         ts.add(s8);
48 
49         // 遍历
50         // 如果不重写自然排序方法,就会报错,因为没有给定如何排序,也没有保证唯一性
51         // java.lang.ClassCastException: com.wyh.treeSet.Student cannot be cast to
52         // java.lang.Comparable
53         for (Student2 s : ts) {
54             System.out.println(s.getName() + "---" + s.getAge());
55         }
56 
57     }
58 
59 }

方式2、用匿名内部类的方式实现:

 1 package com.wyh.treeSet2;
 2 
 3 import java.util.Comparator;
 4 import java.util.TreeSet;
 5 
 6 /**
 7  * @author WYH
 8  * @version 2019年11月17日 下午2:27:13
 9  * 
10  *          根据年龄的长度进行排序
11  */
12 public class TreeSetDemo03 {
13     public static void main(String[] args) {
14 //        TreeSet<Student2> ts = new TreeSet<Student2>();
15 //        TreeSet<Student2> ts = new TreeSet<Student2>(new MyComparator());
16         
17         //如果一个方法的参数是接口,那么真正要的是实现这个接口的实现类
18         //匿名内部类可以是实现
19         TreeSet<Student2> ts = new TreeSet<Student2>(new Comparator<Student2>(){
20             @Override
21             public int compare(Student2 s1, Student2 s2) {
22                 int num = s1.getName().length() - s2.getName().length();
23                 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
24                 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
25                 return num3;
26             }
27         });
28  
29         // 创建学生对象
30         Student2 s1 = new Student2("王友虎", 22);
31         Student2 s2 = new Student2("赵以浩", 24);
32         Student2 s3 = new Student2("齐博源", 21);
33         Student2 s4 = new Student2("李先锋", 23);
34         Student2 s5 = new Student2("李宏灿", 22);
35         Student2 s6 = new Student2("薛长城", 23);
36         Student2 s7 = new Student2("黄天祥", 24);
37         Student2 s8 = new Student2("王友虎", 23);
38 
39         // 添加到TreeSet中
40         ts.add(s1);
41         ts.add(s2);
42         ts.add(s3);
43         ts.add(s4);
44         ts.add(s5);
45         ts.add(s6);
46         ts.add(s7);
47         ts.add(s8);
48 
49         // 遍历
50         // 如果不重写自然排序方法,就会报错,因为没有给定如何排序,也没有保证唯一性
51         // java.lang.ClassCastException: com.wyh.treeSet.Student cannot be cast to
52         // java.lang.Comparable
53         for (Student2 s : ts) {
54             System.out.println(s.getName() + "---" + s.getAge());
55         }
56 
57     }
58 
59 }

  (4)案例:

    A: 获取无重复的随机数(HashSet实现)

 1 package com.wyh.HashSet_random;
 2 
 3 import java.util.Arrays;
 4 import java.util.HashSet;
 5 import java.util.Random;
 6 
 7 /** 
 8 * @author WYH
 9 * @version 2019年11月17日 下午3:14:10
10 * 
11 * 实现10个1-20的随机数
12 * 
13 * 
14 * 
15 */
16 public class HashSet_random_Demo {
17     public static void main(String[] args) {
18         //创建随机数对象
19         Random r = new Random();
20         
21         //创建HashSet集合
22         HashSet<Integer> hs = new HashSet<Integer>();
23         
24         //判断元素是否小于10
25         while(hs.size()<10) {
26            int num = r.nextInt(20)+1;
27            hs.add(num);
28         }
29         
30         Object[] obj = hs.toArray();
31         Arrays.sort(obj);
32         
33         //遍历集合
34         for(Object i : obj) {
35             System.out.println(i);
36         }
37     }
38 }

    B: 键盘录入学生按照总分从搞到底输出(TreeSet且用匿名内部类实现)

 1 package TreeSet_Scanner;
 2 
 3 import java.util.Comparator;
 4 import java.util.Scanner;
 5 import java.util.TreeSet;
 6 
 7 
 8 /** 
 9 * @author WYH
10 * @version 2019年11月17日 下午3:25:25
11 * 
12 * 键盘录入5个学生信息,并且按照总分高低排序
13 */
14 public class大数据之路week01--自学之集合_1

大数据之路week01--自学之集合_2(Iterator迭代器)

week5

小菜鸡进阶之路_Second week之元组列表集合字典对比.

我的学习之路_第六章_迭代器,泛型

大数据第十九天