============================================================================= ============================================================================= 涉及到的知识点有: 1:用户登录注册案例(集合版)(理解) 2:Set集合(理解) (1)Set集合的特点 (2)HashSet集合(掌握) (3)TreeSet集合(理解) (4)案例 3:Collection集合总结(掌握) 4:针对Collection集合我们到底使用谁呢?(掌握) 5:在集合中常见的数据结构(掌握) ============================================================================= ============================================================================= 1:用户登录注册案例(集合版)(理解) ----------------------------------------------------------------------------- 2:Set集合(理解) (1)Set集合的特点 无序:存和取的顺序不一致,无索引,不可以存储重复元素(唯一) --------------------------------------- (2)HashSet集合(掌握) A:底层的数据结构是哈希表(是一个元素为链表的数组)
B:哈希表底层依赖两个方法:hashCode()和equals() 执行顺序: 首先比较哈希值是否相同 相同:继续执行equals()方法 返回true:元素重复了,不添加 返回false:直接把元素添加到集合 不相同:就直接把元素添加到集合 C:如何保证元素唯一性的呢? 由hashCode()和equals()保证的。 即:int hashCode() boolean equals(Object obj) D:开发的时候,代码非常的简单,自动生成即可。 E:案例 1.HashSet存储字符串并遍历(注意:字符串默认重写了hasCode()和equals()方法) 2.HashSet存储自定义对象并遍历(对象的成员变量值都相同即为同一个元素) F:LinkedHashSet:底层的数据结构由哈希表和链表组成。 哈希表保证元素的唯一性。 链表保证元素有序。(存储和取出顺序一致) 注意事项: 1.一般来说,不同的字符串的哈希值是不同的。 哈希值仅仅是逻辑值,可能一样。 地址值是实际的物理值,不一样。 2.HashSet:它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。 注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序, 而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。
--------------------------------------- (3)TreeSet集合(理解) A:底层数据结构是红黑树(是一个自平衡的二叉树)(自平衡:说明其结构不会太深)
B:保证元素的排序方式(具体那种方式取决于使用TreeSet的构造方法) a:自然排序(元素具备比较性) 让元素所属的类实现自然排序 Comparable接口。
示例代码如下:
1 package cn.itcast_06;
2
3 /*
4 * 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口,然后重写compareTo()方法
5 */
6 public class Student implements Comparable<Student>{
7 private String name;
8 private int age;
9
10 public Student() {
11 super();
12 }
13
14 public Student(String name, int age) {
15 super();
16 this.name = name;
17 this.age = age;
18 }
19
20 public String getName() {
21 return name;
22 }
23
24 public void setName(String name) {
25 this.name = name;
26 }
27
28 public int getAge() {
29 return age;
30 }
31
32 public void setAge(int age) {
33 this.age = age;
34 }
35
36 @Override
37 public int compareTo(Student s) {
38 // 主要条件:姓名的长度
39 int num = this.name.length() - s.name.length();
40 // 次要条件1:姓名的长度相同,不代表姓名的内容相同
41 int num2 = (num == 0 ? this.name.compareTo(s.name) : num);
42 // 次要条件2:姓名的长度和内容相同,不代表年龄也相同,所以还得继续比较年龄
43 int num3 = (num2 == 0 ? this.age - s.age : num2);
44 return num3;
45 }
46
47 }
1 package cn.itcast_06;
2
3 import java.util.TreeSet;
4
5 /*
6 * TreeSet存储自定义对象并保证排序和唯一
7 *
8 * 需求:请按照姓名的长度排序。
9 *
10 * TreeSet集合保证元素排序和唯一性的原理:
11 * 唯一性:是根据比较的返回是否是0来决定。
12 * 排序:
13 * A:自然排序(元素具备比较性)
14 * 让元素所属的类实现自然排序 Comparable接口。
15 * B:比较器排序(集合具备比较性)
16 * 让集合的构造方法接收一个比较器接口 Comparator的实现类对象,一般用匿名内部类实现。
17 */
18 public class TreeSetDemo {
19 public static void main(String[] args) {
20 // 创建集合对象
21 // TreeSet的构造方法:public TreeSet() // 自然排序
22 TreeSet<Student> ts = new TreeSet<Student>();
23
24 // 创建元素对象
25 Student s1 = new Student("linqingxia", 27);
26 Student s2 = new Student("zhangguorong", 29);
27 Student s3 = new Student("wanglihong", 23);
28 Student s4 = new Student("linqingxia", 27);
29 Student s5 = new Student("liushishi", 22);
30 Student s6 = new Student("wuqilong", 40);
31 Student s7 = new Student("fengqingy", 22);
32 Student s8 = new Student("linqingxia", 29);
33
34 // 添加元素到集合
35 ts.add(s1);
36 ts.add(s2);
37 ts.add(s3);
38 ts.add(s4);
39 ts.add(s5);
40 ts.add(s6);
41 ts.add(s7);
42 ts.add(s8);
43
44 // 遍历集合
45 for (Student s : ts) {
46 System.out.println(s.getName() + "---" + s.getAge());
47 }
48 }
49 }
b:比较器排序(集合具备比较性) 让集合的构造方法接收一个比较器接口 Comparator的实现类对象,一般用匿名内部类实现。
示例代码如下:
(1)用自己新建的实现类实现
1 package cn.itcast_07;
2
3 /*
4 * 如果一个类的元素要想能够进行比较器排序。
5 */
6 public class Student {
7 private String name;
8 private int age;
9
10 public Student() {
11 super();
12 }
13
14 public Student(String name, int age) {
15 super();
16 this.name = name;
17 this.age = age;
18 }
19
20 public String getName() {
21 return name;
22 }
23
24 public void setName(String name) {
25 this.name = name;
26 }
27
28 public int getAge() {
29 return age;
30 }
31
32 public void setAge(int age) {
33 this.age = age;
34 }
35
36 }
1 package cn.itcast_07;
2
3 import java.util.Comparator;
4
5 public class MyComparator implements Comparator<Student> {
6
7 @Override
8 public int compare(Student s1, Student s2) {
9 // return 0;
10
11 // 需求:请按照姓名的长度排序
12 // int num = this.name.length() - s.name.length();
13 // this --> s1 // s1不能直接访问name,因为s1是在MyComparator类中,而name是在Student类中,要想访问,需要通过getXxx()方法
14 // s --> s2
15
16 // 姓名长度
17 int num = s1.getName().length() - s2.getName().length();
18 // 姓名内容
19 int num2 = (num == 0 ? s1.getName().compareTo(s2.getName()) : num);
20 // 年龄
21 int num3 = (num2 == 0 ? s1.getAge() - s2.getAge() : num2);
22 return num3;
23 }
24
25 }
1 package cn.itcast_07;
2
3 import java.util.TreeSet;
4
5 /*
6 * 需求:请按照姓名的长度排序
7 *
8 * TreeSet集合保证元素排序和唯一性的原理:
9 * 唯一性:是根据比较的返回是否是0来决定。
10 * 排序:
11 * A:自然排序(元素具备比较性)
12 * 让元素所属的类实现自然排序 Comparable接口。
13 * B:比较器排序(集合具备比较性)
14 * 让集合的构造方法接收一个比较器接口 Comparator的实现类对象,一般用匿名内部类实现。
15 */
16 public class TreeSetDemo {
17 public static void main(String[] args) {
18 // 创建集合对象
19 // TreeSet的构造方法:public TreeSet(Comparator<? super E> comparator) // 比较器排序,传递的数据类型是引用数据类型中的接口,说明传递的是实现类对象
20 TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()); // 示例:自己写了个具体实现类MyMyComparator,并重写compare()方法
21
22 // 创建元素对象
23 Student s1 = new Student("linqingxia", 27);
24 Student s2 = new Student("zhangguorong", 29);
25 Student s3 = new Student("wanglihong", 23);
26 Student s4 = new Student("linqingxia", 27);
27 Student s5 = new Student("liushishi", 22);
28 Student s6 = new Student("wuqilong", 40);
29 Student s7 = new Student("fengqingy", 22);
30 Student s8 = new Student("linqingxia", 29);
31
32 // 添加元素到集合
33 ts.add(s1);
34 ts.add(s2);
35 ts.add(s3);
36 ts.add(s4);
37 ts.add(s5);
38 ts.add(s6);
39 ts.add(s7);
40 ts.add(s8);
41
42 // 遍历集合
43 for (Student s : ts) {
44 System.out.println(s.getName() + "---" + s.getAge());
45 }
46 }
47 }
(2)用用匿名内部类实现
1 package cn.itcast_07;
2
3 /*
4 * 如果一个类的元素要想能够进行比较器排序。
5 */
6 public class Student {
7 private String name;
8 private int age;
9
10 public Student() {
11 super();
12 }
13
14 public Student(String name, int age) {
15 super();
16 this.name = name;
17 this.age = age;
18 }
19
20 public String getName() {
21 return name;
22 }
23
24 public void setName(String name) {
25 this.name = name;
26 }
27
28 public int getAge() {
29 return age;
30 }
31
32 public void setAge(int age) {
33 this.age = age;
34 }
35
36 }
1 package cn.itcast_07;
2
3 import java.util.Comparator;
4 import java.util.TreeSet;
5
6 /*
7 * 需求:请按照姓名的长度排序
8 *
9 * TreeSet集合保证元素排序和唯一性的原理:
10 * 唯一性:是根据比较的返回是否是0来决定。
11 * 排序:
12 * A:自然排序(元素具备比较性)
13 * 让元素所属的类实现自然排序 Comparable接口。
14 * B:比较器排序(集合具备比较性)
15 * 让集合的构造方法接收一个比较器接口 Comparator的实现类对象,一般用匿名内部类实现。
16 */
17 public class TreeSetDemo {
18 public static void main(String[] args) {
19 // 创建集合对象
20 // TreeSet的构造方法:public TreeSet() // 自然排序
21 // TreeSet<Student> ts = new TreeSet<Student>();
22
23 // TreeSet的构造方法:public TreeSet(Comparator<? super E> comparator) // 比较器排序,传递的数据类型是引用数据类型中的接口,说明传递的是实现类对象
24 // TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()); // 示例:自己写了个具体实现类MyComparator,并重写compare()方法
25
26 // 如果一个方法的参数是接口,那么真正需要的是接口的实现类的对象,而且该方法只调用一次。
27 // 所以使用匿名内部类就可以实现这个东西,这样就不用自己去重新写一个具体的实现类了。其实这种方式是很常见的。
28 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
29 @Override
30 public int compare(Student s1, Student s2) {
31 // 姓名长度
32 int num = s1.getName().length() - s2.getName().length();
33 // 姓名内容
34 int num2 = (num == 0 ? s1.getName().compareTo(s2.getName()) : num);
35 // 年龄
36 int num3 = (num2 == 0 ? s1.getAge() - s2.getAge() : num2);
37 return num3;
38 }
39 });
40
41 // 创建元素对象
42 Student s1 = new Student("linqingxia", 27);
43 Student s2 = new Student("zhangguorong", 29);
44 Student s3 = new Student("wanglihong", 23);
45 Student s4 = new Student("linqingxia", 27);
46 Student s5 = new Student("liushishi", 22);
47 Student s6 = new Student("wuqilong", 40);
48 Student s7 = new Student("fengqingy", 22);
49 Student s8 = new Student("linqingxia", 29);
50
51 // 添加元素到集合
52 ts.add(s1);
53 ts.add(s2);
54 ts.add(s3);
55 ts.add(s4);
56 ts.add(s5);
57 ts.add(s6);
58 ts.add(s7);
59 ts.add(s8);
60
61 // 遍历集合
62 for (Student s : ts) {
63 System.out.println(s.getName() + "---" + s.getAge());
64 }
65 }
66 }
C:把我们讲过的代码看一遍即可 (4)案例 A:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
1.用集合HashSet实现
1 package cn.itcast_08;
2
3 import java.util.HashSet;
4 import java.util.Random;
5
6 /*
7 * 编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
8 *
9 * 分析:
10 * A:创建随机数对象
11 * B:创建一个HashSet集合
12 * C:判断集合的长度是不是小于10,因为Integer包装类默认实现了Comparable接口,所以Integer类能自动判断是否有重复元素
13 * 是:就创建一个随机数添加
14 * 否:不搭理它
15 * D:遍历HashSet集合
16 */
17 public class HashSetDemo {
18 public static void main(String[] args) {
19 // 创建随机数对象
20 Random r = new Random();
21
22 // 创建一个HashSet集合
23 HashSet<Integer> hs = new HashSet<Integer>();
24
25 // 判断集合的长度是不是小于10,因为Integer包装类默认实现了Comparable接口,所以Integer类能自动判断是否有重复元素
26 while (hs.size() < 10) {
27 int num = r.nextInt(20) + 1;
28 hs.add(num);
29 }
30
31 // 遍历HashSet集合
32 for (Integer i : hs) {
33 System.out.println(i);
34 }
35 }
36 }
2.用集合ArrayList实现
1 package cn.itcast_02;
2
3 import java.util.ArrayList;
4 import java.util.Random;
5
6 /*
7 * 获取10个1-20之间的随机数,要求不能重复
8 *
9 * 用数组实现,但是数组的长度是固定的。
10 * 长度不好确定,所以我们使用集合实现。
11 *
12 * 分析:
13 * A:创建产生随机数的对象。
14 * B:创建一个存储随机数的集合ArrayList。
15 * C:定义一个统计变量。从0开始。
16 * D:判断统计遍历是否小于10
17 * 是:产生一个随机数,判断该随机数在集合中是否存在。
18 * 如果不存在:就添加,统计变量++。
19 * 如果存在:就不搭理它。
20 * 否:不搭理它
21 * E:遍历ArrayList集合
22 */
23 public class ArrayListDemo {
24 public static void main(String[] args) {
25 // 创建产生随机数的对象。
26 Random r = new Random();
27
28 // 创建一个存储随机数的集合。
29 ArrayList<Integer> array = new ArrayList<Integer>();
30
31 // 定义一个统计变量。从0开始。
32 int count = 0;
33
34 // 判断统计遍历是否小于10
35 while (count < 10) {
36 // 产生一个随机数
37 int number = r.nextInt(20) + 1;
38
39 // 判断该随机数在集合中是否存在。
40 if (!array.contains(number)) {
41 // 如果不存在:就添加,统计变量++。
42 array.add(number);
43 count++;
44 }
45 }
46
47 // 遍历集合
48 for (Integer i : array) {
49 System.out.println(i);
50 }
51 }
52 }
B:键盘录入5个学生信息(姓名、语文成绩、数学成绩、英语成绩),按照总分从高到低输出到控制台。
1 package cn.itcast_09;
2
3 public class Student {
4 // 姓名
5 private String name;
6 // 语文成绩
7 private int chinese;
8 // 数学成绩
9 private int math;
10 // 英语成绩
11 private int english;
12
13 public Student() {
14 super();
15 }
16
17 public Student(String name, int chinese, int math, int english) {
18 super();
19 this.name = name;
20 this.chinese = chinese;
21 this.math = math;
22 this.english = english;
23 }
24
25 public String getName() {
26 return name;
27 }
28
29 public void setName(String name) {
30 this.name = name;
31 }
32
33 public int getChinese() {
34 return chinese;
35 }
36
37 public void setChinese(int chinese) {
38 this.chinese = chinese;
39 }
40
41 public int getMath() {
42 return math;
43 }
44
45 public void setMath(int math) {
46 this.math = math;
47 }
48
49 public int getEnglish() {
50 return english;
51 }
52
53 public void setEnglish(int english) {
54 this.english = english;
55 }
56
57 public int getSum() {
58 return this.chinese + this.math + this.english;
59 }
60 }
1 package cn.itcast_09;
2
3 import java.util.Comparator;
4 import java.util.Scanner;
5 import java.util.TreeSet;
6
7 /*
8 * 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
9 *
10 * 分析:
11 * A:定义学生类
12 * B:创建一个TreeSet集合
13 * C:总分从高到底如何实现呢?
14 * D:键盘录入5个学生信息
15 * E:遍历TreeSet集合
16 */
17 public class TreeSetDemo {
18 public static void main(String[] args) {
19 // 创建一个TreeSet集合
20 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
21 @Override
22 public int compare(Student s1, Student s2) {
23 // 总分从高到低
24 int num = s2.getSum() - s1.getSum();
25 // 总分相同的不一定语文相同
26 int num2 = (num == 0 ? s1.getChinese() - s2.getChinese() : num);
27 // 总分和语文相同的不一定数序相同
28 int num3 = (num2 == 0 ? s1.getMath() - s2.getMath() : num2);
29 // 总分、语文和数学相同的不一定英语相同
30 int num4 = (num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3);
31 // 总分、语文、数学和英语相同的姓名还不一定相同
32 int num5 = (num4 == 0 ? s1.getName().compareTo(s2.getName()) : num4);
33 return num5;
34 }
35 });
36
37 System.out.println("学生信息录入开始");
38 // 键盘录入5个学生信息
39 for (int x = 1; x <= 5; x++) {
40 Scanner sc = new Scanner(System.in);
41
42 System.out.println("请输入第" + x + "个学生的姓名:");
43 String name = sc.nextLine();
44
45 System.out.println("请输入第" + x + "个学生的语文成绩:");
46 String chineseString = sc.nextLine();
47
48 System.out.println("请输入第" + x + "个学生的数学成绩:");
49 String mathString = sc.nextLine();
50
51 System.out.println("请输入第" + x + "个学生的英语成绩:");
52 String englishString = sc.nextLine();
53
54 // 把录入的数据封装到学生对象中
55 Student s = new Student();
56 s.setName(name);
57 s.setChinese(Integer.parseInt(chineseString)); // 把字符串类型转换为int类型
58 s.setMath(Integer.parseInt(mathString)); // 把字符串类型转换为int类型
59 s.setEnglish(Integer.parseInt(englishString)); // 把字符串类型转换为int类型
60
61 // 把学生对象添加到集合
62 ts.add(s);
63 }
64 System.out.println("学生信息录入完毕");
65
66 System.out.println("学习信息从高到低排序如下:");
67 System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");
68 // 遍历TreeSet集合
69 for (Student s : ts) {
70 System.out.println(s.getName() + "\t" + s.getChinese() + "\t" + s.getMath() + "\t" + s.getEnglish());
71 }
72 }
73 }
----------------------------------------------------------------------------- 3:Collection集合总结(掌握)
Collection
|--List 有序,元素可重复
|--ArrayList
底层数据结构是数组。查询快,增删慢。
线程不安全,效率高
|--Vector
底层数据结构是数组。查询快,增删慢。
线程安全,效率低
|--LinkedList
底层数据结构是链表。查询慢,增删快。
线程不安全,效率高
|--Set 无序,元素唯一
|--HashSet
底层数据结构是哈希表。
如何保证元素唯一性的呢?
依赖两个方法:hashCode()和equals()
开发中自动生成这两个方法即可。
|--LinkedHashSet
底层数据结构是链表和哈希表。
由链表保证元素有序。
由哈希表保证元素唯一。
|--TreeSet
底层数据结构是红黑树(二叉树)。
如何保证元素排序的呢?
自然排序
比较器排序
如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定。
----------------------------------------------------------------------------- 4:针对Collection集合我们到底使用谁呢?(掌握)
元素唯一吗?
是:用Set
元素排序吗?
是:TreeSet
否:HashSet
如果你知道是用Set,但是不知道是用哪个Set,就用HashSet。
否:用List
要安全吗?
是:Vector
否:ArrayList 或者 LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是用List,但是不知道是用哪个List,就用ArrayList。
---------------------------------------
如果你知道是用 Collection 集合,但是不知道使用谁,就用 ArrayList。
如果你仅仅知道用集合,就用ArrayList。
由此可见,ArrayList用的最多。
----------------------------------------------------------------------------- 5:在集合中常见的数据结构(掌握)
ArrayXxx: 底层数据结构是数组,查询快,增删慢。 LinkedXxx: 底层数据结构是链表,查询慢,增删快。 HashXxx: 底层数据结构是哈希表。依赖两个方法:hashCode()和equals()。 TreeXxx: 底层数据结构是二叉树。两种方式排序:自然排序和比较器排序。 =============================================================================