=============================================================================
=============================================================================
涉及到的知识点有:
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: 底层数据结构是二叉树。两种方式排序:自然排序和比较器排序。
=============================================================================
我的博客园地址: http://www.cnblogs.com/chenmingjun
我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun
Copyright ©2018 黑泽明军
【转载文章务必保留出处和署名,谢谢!】