1. 异常 1.1 异常的概述
Error:严重问题,不需要处理 Exception:称为异常类,它表示程序本身可以处理的问题
RuntimeException:在编译期是不检查的,出现问题后,需要我们回来修改代码
非RuntimeException:编译期就必须处理的,否则程序不能粉通过编译,就更不能正常运行了
1.2 JVM的默认处理方案 如果程序出现了问题,我们没有做任何处理,最终JVM会做默认的处理
把异常的名称,异常原因及异常出现的位置等信息输出在了控制台
程序停止执行
1.3 异常处理try…catch…
1 2 3 4 5 try { }catch (异常类名 变量名){ }
程序从try里面的代码开始执行
出现异常,会自动生成一个异常类对象,该异常对象将被提交给Java运行时系统
当Java运行时系统接收到异常对象时,会到catch中去找匹的异常类,找到后进行异常的处理
执行完毕之后,程序还可以继续往下执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package demo_01;public class ExceptionDemo { public static void main (String[] args) { System.out.println("开始" ); method(); System.out.println("结束" ); } public static void method () { int [] arr = {15 , 22 , 66 , 88 }; try { System.out.println(arr[4 ]); }catch (ArrayIndexOutOfBoundsException e){ System.out.println("访问的索引越界" ); e.printStackTrace(); } } }
1.4 Throwable的成员方法
方法名
说明
public String getMessage()
返回此throwable的详细消息字符串
public String toString()
返回此可抛出的简短描述
public void printStackTrace()
把异常的错误信息输出在控制台
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 package demo_01;public class ExceptionDemo { public static void main (String[] args) { System.out.println("开始" ); method(); System.out.println("结束" ); } public static void method () { int [] arr = {15 , 22 , 66 , 88 }; try { System.out.println(arr[4 ]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e.toString()); System.out.println("------------" ); System.out.println(e.getMessage()); System.out.println("------------" ); e.printStackTrace(); } } } 开始 java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4 ------------ Index 4 out of bounds for length 4 ------------ 结束 java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4 at demo_01.ExceptionDemo.method(ExceptionDemo.java:18 ) at demo_01.ExceptionDemo.main(ExceptionDemo.java:11 )
1.5 编译时异常和运行时异常的区别 Java中的异常被分为两大类:编译时异常 和运行时异常 ,也被称为受检异常 和非受检异常 所有的RuntimeException类及其子类被称为运行时异常,其他的异常都是编译时异常
编译时异常:必须显示处理,否则程序就会发生错误,无法通过编译
运行时异常:无需显示处理,也可以和编译时异常一样处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package demo_01;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class ExceptionDemo_02 { public static void main (String[] args) { method(); method2(); } public static void method () { try { String s = "2022-04-24" ; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd" ); Date d = sdf.parse(s); System.out.println(d); } catch (ParseException e) { e.printStackTrace(); } } public static void method2 () { try { int [] arr = {55 , 88 , 99 }; System.out.println(arr[3 ]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("访问索引越界" ); } } }
1.6 异常处理之throws 虽然我们通过ty…catch…可以对异常进行处理,但是并不是所有的情况我们都有权限进行异常的处理 也就是说,有些时候可能出现的异常是我们处理不了的,这个时候该怎么办呢? 针对这种情况,Java提供了throws的处理方案
注意:这个格式是跟在方法的括号后面的
编译时异常必须要进行处理,两种处理方案:try…catch…或者throws,如果采用throws这种方案,将来谁调用谁处理
运行时异常可以不处理,出现问题后,需要我们回来修改代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package demo_01;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class ThrowsDemo { public static void main (String[] args) { System.out.println("开始" ); try { method(); } catch (ParseException e) { e.printStackTrace(); } System.out.println("结束" ); } public static void method () throws ParseException { String s = "2022-04-24" ; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd" ); Date d = sdf.parse(s); System.out.println(d); } }
1.7 自定义异常
1 2 3 4 5 6 7 8 9 10 11 12 public class 异常类名 extends Exception { } public class ScoreException extends Exception { public ScoreException () {} public ScoreException (String message) { super (message); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 package scoreDemo;public class ScoreException extends Exception { public ScoreException () { } public ScoreException (String message) { super (message); } } package scoreDemo;public class Teacher { public void checkScore (int score) throws ScoreException { if (score<0 ||score>100 ){ throw new ScoreException("分数输入的不正确" ); }else { System.out.println("分数正确" ); } } } package scoreDemo;import java.util.Scanner;public class TeacherDemo { public static void main (String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入分数:" ); int score = sc.nextInt(); Teacher t= new Teacher(); try { t.checkScore(score); } catch (ScoreException e) { e.printStackTrace(); } } } 请输入分数:98 分数正确 请输入分数:150 scoreDemo.ScoreException: 分数输入的不正确 at scoreDemo.Teacher.checkScore(Teacher.java:6 ) at scoreDemo.TeacherDemo.main(TeacherDemo.java:13 )
1.8 throws和throw的区别
throws
throw
用在方法声明后面,跟的是异常类名
用在方法体内,跟的是异常对象名
表示抛出异常,由该方法的调用者来处理
表示抛出异常,由方法体内的语句处理
表示出现异常的一种可能性,并不一定会发生这些异常
执行throw一定抛出了某种异常
2.Collection 集合的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
2.1 集合体系结构
2.2 Collection集合概述和使用 Collection集合概述
是单列集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
创建Collection集合的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package collectionDemo_01;import java.util.ArrayList;import java.util.Collection;public class CollectionDemo { public static void main (String[] args) { Collection<String> c = new ArrayList<String>(); c.add("张三" ); c.add("李四" ); c.add("王五" ); System.out.println(c); } } [张三, 李四, 王五]
2.3 Collection集合常用方法
方法名
说明
boolean add(E e)
添加元素
boolean remove(Object o)
从集合中移除指定的元素
void clear()
清空集合中的元素
boolean contains(Object o)
判断集合中是否存在指定的元素
boolean isEmpty()
判断集合是否为空
int size()
集合的长度,也就是集合中元素的个数
2.4 Collection集合的遍历 Iterator:迭代器,集合的专用遍历方式
Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
Iterator中的常用方法:
E next():返回迭代中的下一个元素
boolean hasNext():如果迭代具有更多元素,则返回true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package collectionDemo_01;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;public class CollectionDemo { public static void main (String[] args) { Collection<String> c = new ArrayList<String>(); c.add("张三" ); c.add("李四" ); c.add("王五" ); Iterator<String> it = c.iterator(); while (it.hasNext()){ String n = it.next(); System.out.println(n); } } } 张三 李四 王五
2.5 集合的使用步骤
2.6 Collection集合存储学生对象并遍历 需求:创建一个存储学生对象的集合,存储3个学生对像,使用程序实现在控制台遍历该集合
思路: ①定义学生类 ②创建Collection集合对像 ③创建学生对象 ④把学生添加到集合 ⑤遍历集合(迭代器方式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 package demo_02;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } } package demo_02;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;public class CollectionDemo { public static void main (String[] args) { Collection<Student> c = new ArrayList<Student>(); Student sc1 = new Student("张三" , 18 ); Student sc2 = new Student("李四" , 19 ); Student sc3 = new Student("王五" , 10 ); c.add(sc1); c.add(sc2); c.add(sc3); Iterator<Student> it = c.iterator(); while (it.hasNext()){ Student n = it.next(); System.out.println(n.getName()+", " +n.getAge()); } } } 张三, 18 李四, 19 王五, 10
3. List 3.1 List集合概述和特点 List集合概述:
有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
与Set集合不同,列表通常允许重复的元素
List集合特点:
有序:存储和取出的元素顺序一致
可重复:存储的元素可以重复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package listDemo_03;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo { public static void main (String[] args) { List<String> list = new ArrayList<>(); list.add("张三" ); list.add("李四" ); list.add("王五" ); list.add("王五" ); System.out.println(list); Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); } } } [张三, 李四, 王五, 王五] 张三 李四 王五 王五
3.2 List集合特有方法
方法名
说明
void add(int index,E element)
在此集合中的指定位置插入指定的元素
E remove(int index)
删除指定索引处的元素,返回被删除的元素
E set(int index,E element)
修改指定索引处的元素,返回被修改的元素
E get(int index)
返回指定索引处的元素
3.3 list集合存储学生对象并遍历 需求:创建一个存储学生对象的集合,存储3个学生对像,使用程序实现在控制台遍历该集合思路: ①定义学生类 ②创建List集合对象 ③创建学生对象 ④把学生添加到集合 ⑤遍历集合(迭代器方式,for循环方式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 package demo_02;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } } package demo_02;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo { public static void main (String[] args) { List<Student> list = new ArrayList<>(); Student sc1 = new Student("张三" , 18 ); Student sc2 = new Student("李四" , 19 ); Student sc3 = new Student("王五" , 10 ); list.add(sc1); list.add(sc2); list.add(sc3); Iterator<Student> it = list.iterator(); while (it.hasNext()){ Student n = it.next(); System.out.println(n.getName()+", " +n.getAge()); } System.out.println("------------" ); for (int i = 0 ;i<list.size(); i++){ Student s = list.get(i); System.out.println(s.getName()+", " +s.getAge()); } } } 张三, 18 李四, 19 王五, 10 ------------ 张三, 18 李四, 19 王五, 10
3.4 Listlterator Listlterator:列表迭代器
通过List集合的listlterator()方法得到,所以说它是List集合特有的迭代器
用于允许程序员沿任一方向遍历列表的列表迭代器,在迭代期间修改列表,并获取巧列表中迭代器的当前位置
Listlterator中的常用方法:
方法名
说明
E next()
返回迭代中的下一个元素
boolean hasNext()
如果迭代具有更多元素,则返回true
E previous()
返回列表中的上一个元素
boolean hasPrevious()
如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true
void add(E e)
将指定的元素插入列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package listDemo_03;import java.util.ArrayList;import java.util.List;import java.util.ListIterator;public class ListIteratorDemo { public static void main (String[] args) { List<String> list = new ArrayList<S>(); list.add("张三" ); list.add("李四" ); list.add("王五" ); ListIterator<String> lit = list.listIterator(); while (lit.hasNext()){ String n = lit.next(); System.out.println(n); } System.out.println("----------" ); while (lit.hasPrevious()){ String b = lit.previous(); System.out.println(b); } } } 张三 李四 王五 ---------- 王五 李四 张三
3.5 增强for循环 增强for:简化数组和Collection集合的遍历
实现Iterable接口的类允许其对象成为增强型for语句的目标
它是DKS之后出现的,其内部原理是一个lterator迭代器
增强for的格式:
1 2 3 4 5 6 7 8 9 10 for (元素数据类型变量名:数组或者Collection集合){ } int [] arr={1 ,2 ,3 ,4 ,5 };for (int i:arr){ System.out.printIn(i) }
3.6 案例:List集合存储学生对像用三种方式遍历 需求:创建一个存储学生对象的集合,存储3个学生对像,使用程序实现在控制台遍历该集合思路: ①定义学生类 ②创建List集合对象 ③创建学生对象 ④把学生添加到集合 ⑤遍历集合 迭代器:集合特有的遍历方式 普通for:带有索引的遍历方式 增强for:最方使的遍历方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 package demo_02;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } } package demo_02;import java.util.ArrayList;import java.util.Iterator;import java.util.List;public class ListDemo { public static void main (String[] args) { List<Student> list = new ArrayList<>(); Student sc1 = new Student("张三" , 18 ); Student sc2 = new Student("李四" , 19 ); Student sc3 = new Student("王五" , 10 ); list.add(sc1); list.add(sc2); list.add(sc3); Iterator<Student> it = list.iterator(); while (it.hasNext()) { Student n = it.next(); System.out.println(n.getName() + ", " + n.getAge()); } System.out.println("------------" ); for (int i = 0 ; i < list.size(); i++) { Student s = list.get(i); System.out.println(s.getName() + ", " + s.getAge()); } System.out.println("------------" ); for (Student sc : list) { System.out.println(sc.getName() + ", " + sc.getAge()); } } } 张三, 18 李四, 19 王五, 10 ------------ 张三, 18 李四, 19 王五, 10 ------------ 张三, 18 李四, 19 王五, 10
3.7 数据结构
数据结构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合
通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率
3.8 常见数据结构之栈
数据进入栈模型的过程称为:压/进栈
数据离开栈模型的过程称为:弹/出栈
栈是一种数据先进后出的模型
3.9 常见数据结构之队列
数据从后端进入队列模型的过程称为:入队列
数据从前端离开队列模型的过程称为:出队列
队列是一种数据先进先出的模型
3.10 常见数据结构之数组
数组是一种查询快,增删慢的模型
查询数据通过索引定位,查询任意数据耗时相同,查询效率高
删除数据时,要将原始数据删除,同时后面每个数据前移,删除效率低
添加数据时,添加位置后的每个数据后移,再添加元素,添加效率极低
3.11 常见数据结构之链表
3.11.1 添加数据 在数据AC之间添加一个数据B,保存在地址54位置
在数据B对应的下一个数据地址指向数据C
在数据A对应的下一个数据地址指向数据B
3.11.2 删除数据 在数据AC之间添加一个数据B,保存在地址54位置,删除数据BD之间的数据C
数据B对应的下一个数据地址指向数据D
数据C删除
3.11.3 链表查询
查询数据D是否存在,必须从头(head)开始查询
查询第3个数据,必须从头(head)开始查询
链表是一种增删快的模型(对比数组)
链表是一种查询慢的模型(对比数组)
3.12 List集合子类特点 List集合常用子类:ArrayList, LinkedList
ArrayList::底层数据结构是数组,查询快,增删慢
LinkedList:底层数据结构是链表,查询慢,增删快
练习:
分别使用ArrayLista和LinkedList完成存储字符串并遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package myList;import java.util.ArrayList;import java.util.LinkedList;public class ListDemo { public static void main (String[] args) { ArrayList<String> array= new ArrayList<String>(); array.add("张三" ); array.add("李四" ); array.add("hello" ); for (String s : array){ System.out.println(s); } System.out.println("--------------" ); LinkedList<String> linkedList = new LinkedList<String>(); linkedList.add("hello" ); linkedList.add("world" ); linkedList.add("java" ); for (String c : linkedList){ System.out.println(c); } } } 张三 李四 hello -------------- hello world java
3.13 案例:ArrayList集合存储学生对象用三种方式遍历 需求:创建一个存储学生对象的集合,存储3个学生对像,使用程序实现在控制台遍历该集合思路: ①定义学生类 ②创建ArrayList集合对像 ③创建学生对象 ④把学生添加到集合 ⑤遍历集合 迭代器:集合特有的遍历方式 普通for:带有索引的遍历方式 增强for:最方便的遍历方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 package demo_02;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } } package demo_02;import java.util.ArrayList;import java.util.Iterator;public class ArrayListDemo { public static void main (String[] args) { ArrayList<Student> array = new ArrayList<Student>(); Student sc1 = new Student("张三" , 18 ); Student sc2 = new Student("李四" , 19 ); Student sc3 = new Student("王五" , 10 ); array.add(sc1); array.add(sc2); array.add(sc3); Iterator<Student> it = array.iterator(); while (it.hasNext()){ Student s = it.next(); System.out.println(s.getName()+", " + s.getAge()); } System.out.println("-----------" ); for (int i = 0 ; i<array.size(); i++){ Student s1 = array.get(i); System.out.println(s1.getName()+", " + s1.getAge()); } System.out.println("-----------" ); for (Student s2 : array){ System.out.println(s2.getName()+", " + s2.getAge()); } } } 张三, 18 李四, 19 王五, 10 ----------- 张三, 18 李四, 19 王五, 10 ----------- 张三, 18 李四, 19 王五, 10
3.14 LinkedList集合的特有功能
方法名
说明
public void addFirst(E e)
在该列表开头插入指定的元素
public void addLast(E e)
将指定的元素追加到此列表的末尾
public E getFirst()
返回此列表中的第一个元素
public E getLast()
返回此列表中的最后一个元素
public E removeFirst()
从此列表中删除并返回第一个元素
public E removeLast()
从此列表中删除并返回最后一个元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 package myList;import java.util.LinkedList;public class LinkdeListDemo { public static void main (String[] args) { LinkedList<String> linkdeList = new LinkedList<String>(); linkdeList.add("hello" ); linkdeList.add("world" ); linkdeList.add("java" ); linkdeList.addFirst("javase" ); linkdeList.addLast("javaee" ); System.out.println(linkdeList.getFirst()); System.out.println(linkdeList.getLast()); System.out.println(linkdeList.removeFirst()); System.out.println(linkdeList.removeLast()); } } javase javaee javase javaee
4. set 4.1 set集合的概述和特点 Set集合特点
不包含重复元素的集合
没有带索引的方法,所以不能使用普通for循环遍历
Set集合练习:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package demo_01;import java.util.HashSet;import java.util.Set;public class SetDemo { public static void main (String[] args) { Set<String> set = new HashSet<String>(); set.add("hello" ); set.add("java" ); set.add("world" ); set.add("java" ); for (String s : set) { System.out.println(s); } } } java world hello
4.2 哈希值 哈希值 :是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
public int hashCode():返回对象的哈希码值
对象的哈希值特点
同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 package demo_02;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } } package demo_02;public class HashDemo { public static void main (String[] args) { Student s1 = new Student("张三" ,18 ); System.out.println(s1.hashCode()); System.out.println(s1.hashCode()); Student s2 = new Student("张三" ,18 ); System.out.println(s2.hashCode()); System.out.println("-----------" ); System.out.println("java" .hashCode()); System.out.println("world" .hashCode()); System.out.println("java" .hashCode()); System.out.println("-----------" ); System.out.println("重地" .hashCode()); System.out.println("通话" .hashCode()); } }
4.3 HashSet:集合概述和特点 HashSet集合特点:
底层数据结构是哈希表
对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以是不包含重复元素的集合
HashSet集合练习:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package demo_03;import java.util.HashSet;public class HashSetDemo { public static void main (String[] args) { HashSet<String> hs = new HashSet<String>(); hs.add("hello" ); hs.add("world" ); hs.add("java" ); hs.add("world" ); for (String s : hs) { System.out.println(s); } } } world java hello
4.4 常见数据结构之哈希表 哈希表
JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组
JDK8以后,在长度比较长的时候,底层实现了优化
4.5 案例:HashSet集合存储学生对像并遍历 需求:创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合 要求:学生对象的成员变量值相同,我们就认为是同一个对像 思路: ①定义学生类 ②创建HashSet集合对象 ③创建学生对像 ④把学生添加到集合 ⑤遍历集合(增强for)⑥在学生类中重写两个方法 hashCode()和equals() 自动生成即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 package demo_03;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } @Override public boolean equals (Object o) { if (this == o) return true ; if (o == null || getClass() != o.getClass()) return false ; Student student = (Student) o; if (age != student.age) return false ; return name != null ? name.equals(student.name) : student.name == null ; } @Override public int hashCode () { int result = name != null ? name.hashCode() : 0 ; result = 31 * result + age; return result; } } package demo_03;import java.util.HashSet;public class HashSetStuDemo { public static void main (String[] args) { HashSet<Student> hs = new HashSet<Student>(); Student s1 =new Student("张三" , 18 ); Student s2 =new Student("李四" , 20 ); Student s3 =new Student("王五" , 19 ); Student s4 =new Student("李四" , 20 ); hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); for (Student sc:hs){ System.out.println(sc.getName()+", " +sc.getAge()); } } } 王五, 19 张三, 18 李四, 20
4.6 LinkedHashSet:集合概述和特点 LinkedHashSet集合特点
哈希表和链表实现的Set接口,具有可预测的迭代次序
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
由哈希表保证元素唯一,也就是说没有重复的元素
LinkedHashSet:集合练习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package demo_04;import java.util.LinkedHashSet;public class LinkedHashSetDemo { public static void main (String[] args) { LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>(); linkedHashSet.add("hello" ); linkedHashSet.add("world" ); linkedHashSet.add("java" ); linkedHashSet.add("world" ); for (String s:linkedHashSet){ System.out.println(s); } } } hello world java
4.7 TreeSet集合概述和特点 TreeSet:集合特点:
元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
(1) TreeSet():根据其元素的自然排序进行排序
(2) TreeSet(Comparator comparator):根据指定的比较器进行排序
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以不包含重复元素的集合
TreeSet集合练习:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package demo_05;import java.util.TreeSet;public class TreeSetDemo { public static void main (String[] args) { TreeSet<Integer> treeSet = new TreeSet<Integer>(); treeSet.add(10 ); treeSet.add(50 ); treeSet.add(30 ); treeSet.add(20 ); treeSet.add(40 ); for (Integer s : treeSet) { System.out.println(s); } } } 10 20 30 40 50
4.8 自然排序Comparable的使用
存储学生对像并遍历,创建TreeSet集合使用无参构造方法
要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
结论:
用TreeSet集合存储自定义对像,无参构造方法使用的是自然排序对元素进行排序的
自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(To)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 package demo_05;public class Student implements Comparable <Student > { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } @Override public int compareTo (Student s) { int num = this .age - s.age; int num2 = num == 0 ?this .name.compareTo(s.name):num; return num2; } } package demo_05;import java.util.TreeSet;public class TreeSetDemo02 { public static void main (String[] args) { TreeSet<Student> ts = new TreeSet<Student>(); Student s1 = new Student("xishi" , 18 ); Student s2 = new Student("wangzhaojun" , 19 ); Student s3 = new Student("diaochan" , 20 ); Student s4 = new Student("yangyuhuan" , 16 ); Student s5 = new Student("chenghanhan" , 20 ); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); for (Student s : ts) { System.out.println(s.getName() + ", " + s.getAge()); } } } yangyuhuan, 16 xishi, 18 wangzhaojun, 19 chenghanhan, 20 diaochan, 20
4.9 比较器排序Comparator的使用
存储学生对象并遍历,创建TreeSet集合使用带参构造方法
要求:按照年龄从小到大排序,年龄相同时,按姓名的字母顺序排序
结论:
用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(To1,To2)方法
重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 package demo_06;public class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = 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; } } package demo_06;import java.util.Comparator;import java.util.TreeSet;public class TreeSetDemo { public static void main (String[] args) { TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare (Student o1, Student o2) { int num = o1.getAge() - o2.getAge(); int num2 = num == 0 ?o1.getName().compareTo(o2.getName()):num; return num2; } }); Student s1 = new Student("xishi" , 18 ); Student s2 = new Student("wangzhaojun" , 19 ); Student s3 = new Student("diaochan" , 20 ); Student s4 = new Student("yangyuhuan" ,22 ); Student s5 = new Student("chenghanhan" , 20 ); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); for (Student s : ts) { System.out.println(s.getName() + ", " + s.getAge()); } } } xishi, 18 wangzhaojun, 19 chenghanhan, 20 diaochan, 20 yangyuhuan, 22
4.10 案例:成绩排序
需求:用TreeSet:集合存储多个学生信息(姓名,语文成绩,数学成绩,并遍历该集合
要求:按照总分从高到低出现
思路:
①定义学生类 ②创建TreeSet集合对象,通过比较器排序进行排序 ③创建学生对象 ④把学生对象添加到集合 ⑤遍历集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 package demo_07;public class Student { private String name; private int chinese; private int math; public Student () { } public Student (String name, int chinese, int math) { this .name = name; this .chinese = chinese; this .math = math; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getChinese () { return chinese; } public void setChinese (int chinese) { this .chinese = chinese; } public int getMath () { return math; } public void setMath (int math) { this .math = math; } public int sum () { return chinese+math; } } package demo_07;import java.util.Comparator;import java.util.TreeSet;public class TreeSetDemo { public static void main (String[] args) { TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { @Override public int compare (Student o1, Student o2) { int num = o1.sum() - o2.sum(); int num2 = num == 0 ?o1.getName().compareTo(o2.getName()):num; return num2; } }); Student s1 = new Student("张三" ,98 ,99 ); Student s2 = new Student("李四" ,95 ,95 ); Student s3 = new Student("王五" ,95 ,99 ); Student s4 = new Student("小陈" ,98 ,100 ); Student s5 = new Student("小尚" ,100 ,99 ); Student s6 = new Student("逸乐" ,95 ,99 ); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); for (Student s:ts){ System.out.println(s.getName()+", " +s.getChinese()+", " +s.getMath()+", " +s.sum()); } } } 李四, 95 , 95 , 190 王五, 95 , 99 , 194 逸乐, 95 , 99 , 194 张三, 98 , 99 , 197 小陈, 98 , 100 , 198 小尚, 100 , 99 , 199
4.11 案例:不重复的随机数 需求:编写一个程序,获取10个1-20之间的随机数,要求随机数不能重复,并在控制台输出
思路:
①创建Set集合对象 ②创建随机数对象 ③判断集合的长度是不是小于10 是:产生一个随机数,添加到集合 回到3继续 ④遍历集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package demo_07;import java.util.HashSet;import java.util.Random;import java.util.Set;import java.util.TreeSet;public class SetDemo { public static void main (String[] args) { Set<Integer> set = new TreeSet<Integer>(); Random r = new Random(); while (set.size() < 10 ) { int num = r.nextInt(20 ) + 1 ; set.add(num); } for (Integer i : set) { System.out.println(i); } } }