JAVA进阶--不可变集合、Stream流、异常--2022年9月4日
作者:互联网
第一节 不可变集合
1、不可变集合的特点
定义完成后不可以修改,或者添加、删除
2、如何创建不可变集合
List、Set、Map接口中,都存在of方法可以创建不可变集合
第二节 Stream流
1、Stream流的作用是什么,结合了什么技术
简化集合,数组操作的API,结合了Lambda表达式
2、说说Stream流的思想和适用步骤
先得到集合或者数组的Stream流(就是一根传送带)
把元素放上去
然后就用这个Stream流简化的API来方便的操作元素
3、Stream流初体验
1 package com.itheima.d2_stream; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.List; 6 7 /** 8 目标:初步体验Stream流的方便与快捷 9 */ 10 public class StreamTest { 11 public static void main(String[] args) { 12 List<String> names = new ArrayList<>(); 13 Collections.addAll(names, "张三丰","张无忌","周芷若","赵敏","张强"); 14 System.out.println(names); 15 // 16 // // 1、从集合中找出姓张的放到新集合 17 // List<String> zhangList = new ArrayList<>(); 18 // for (String name : names) { 19 // if(name.startsWith("张")){ 20 // zhangList.add(name); 21 // } 22 // } 23 // System.out.println(zhangList); 24 // 25 // // 2、找名称长度是3的姓名 26 // List<String> zhangThreeList = new ArrayList<>(); 27 // for (String name : zhangList) { 28 // if(name.length() == 3){ 29 // zhangThreeList.add(name); 30 // } 31 // } 32 // System.out.println(zhangThreeList); 33 34 // 3、使用Stream实现的 35 names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s)); 36 } 37 }Stream流初体验
4、Sream流的获取
===========================================================================
1 package com.itheima.d2_stream; 2 3 import java.util.*; 4 import java.util.stream.Stream; 5 6 /** 7 目标:Stream流的获取 8 9 Stream流式思想的核心: 10 是先得到集合或者数组的Stream流(就是一根传送带) 11 然后就用这个Stream流操作集合或者数组的元素。 12 然后用Stream流简化替代集合操作的API. 13 14 集合获取流的API: 15 (1) default Stream<E> stream(); 16 17 小结: 18 集合获取Stream流用: stream(); 19 数组:Arrays.stream(数组) / Stream.of(数组); 20 */ 21 public class StreamDemo02 { 22 public static void main(String[] args) { 23 /** --------------------Collection集合获取流------------------------------- */ 24 Collection<String> list = new ArrayList<>(); 25 Stream<String> s = list.stream(); 26 27 /** --------------------Map集合获取流------------------------------- */ 28 Map<String, Integer> maps = new HashMap<>(); 29 // 键流 30 Stream<String> keyStream = maps.keySet().stream(); 31 // 值流 32 Stream<Integer> valueStream = maps.values().stream(); 33 // 键值对流(拿整体) 34 Stream<Map.Entry<String,Integer>> keyAndValueStream = maps.entrySet().stream(); 35 36 /** ---------------------数组获取流------------------------------ */ 37 String[] names = {"赵敏","小昭","灭绝","周芷若"}; 38 Stream<String> nameStream = Arrays.stream(names); 39 Stream<String> nameStream2 = Stream.of(names); 40 } 41 }获取Stream流
5、Stream流常用API
终结和非终结方法的含义是什么?
终结方法后流不可以继续使用,非终结方法会返回新的流,支持链式编程
======================================================================================================
1 package com.itheima.d2_stream; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.List; 6 import java.util.function.Consumer; 7 import java.util.function.Function; 8 import java.util.function.Predicate; 9 import java.util.stream.Stream; 10 11 /** 12 目标:Stream流的常用API 13 forEach : 逐一处理(遍历) 14 count:统计个数 15 -- long count(); 16 filter : 过滤元素 17 -- Stream<T> filter(Predicate<? super T> predicate) 18 limit : 取前几个元素 19 skip : 跳过前几个 20 map : 加工方法 21 concat : 合并流。 22 */ 23 public class StreamDemo03 { 24 public static void main(String[] args) { 25 List<String> list = new ArrayList<>(); 26 list.add("张无忌"); 27 list.add("周芷若"); 28 list.add("赵敏"); 29 list.add("张强"); 30 list.add("张三丰"); 31 list.add("张三丰"); 32 33 // Stream<T> filter(Predicate<? super T> predicate) 34 list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s)); 35 36 long size = list.stream().filter(s -> s.length() == 3).count(); 37 System.out.println(size); 38 39 // list.stream().filter(s -> s.startsWith("张")).limit(2).forEach(s -> System.out.println(s)); 40 list.stream().filter(s -> s.startsWith("张")).limit(2).forEach(System.out::println); 41 42 list.stream().filter(s -> s.startsWith("张")).skip(2).forEach(System.out::println); 43 44 // map加工方法: 第一个参数原材料 -> 第二个参数是加工后的结果。 45 // 给集合元素的前面都加上一个:黑马的: 46 list.stream().map(s -> "黑马的:" + s).forEach(a -> System.out.println(a)); 47 48 // 需求:把所有的名称 都加工成一个学生对象。 49 list.stream().map(s -> new Student(s)).forEach(s -> System.out.println(s)); 50 // list.stream().map(Student::new).forEach(System.out::println); // 构造器引用 方法引用 51 52 // 合并流。 53 Stream<String> s1 = list.stream().filter(s -> s.startsWith("张")); 54 Stream<String> s2 = Stream.of("java1", "java2"); 55 // public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 56 Stream<String> s3 = Stream.concat(s1 , s2); 57 s3.distinct().forEach(s -> System.out.println(s)); 58 } 59 }Stream流常用API
6、Stream流的综合应用
1 public class Employee { 2 private String name; 3 private char sex; 4 private double salary; 5 private double bonus; 6 private String punish; // 处罚信息 7 8 public Employee(){ 9 } 10 11 public Employee(String name, char sex, double salary, double bonus, String punish) { 12 this.name = name; 13 this.sex = sex; 14 this.salary = salary; 15 this.bonus = bonus; 16 this.punish = punish; 17 } 18 19 public String getName() { 20 return name; 21 } 22 23 public void setName(String name) { 24 this.name = name; 25 } 26 27 public char getSex() { 28 return sex; 29 } 30 31 public void setSex(char sex) { 32 this.sex = sex; 33 } 34 35 public double getSalary() { 36 return salary; 37 } 38 39 public void setSalary(double salary) { 40 this.salary = salary; 41 } 42 43 public double getBonus() { 44 return bonus; 45 } 46 47 public void setBonus(double bonus) { 48 this.bonus = bonus; 49 } 50 51 public String getPunish() { 52 return punish; 53 } 54 55 public void setPunish(String punish) { 56 this.punish = punish; 57 } 58 59 public double getTotalSalay(){ 60 return salary * 12 + bonus; 61 } 62 63 @Override 64 public String toString() { 65 return "Employee{" + 66 "name='" + name + '\'' + 67 ", sex=" + sex + 68 ", salary=" + salary + 69 ", bonus=" + bonus + 70 ", punish='" + punish + '\'' + 71 '}'+"\n"; 72 } 73 }Employee
1 public class Topperformer { 2 private String name; 3 private double money; // 月薪 4 5 public Topperformer() { 6 } 7 8 public Topperformer(String name, double money) { 9 this.name = name; 10 this.money = money; 11 } 12 13 public String getName() { 14 return name; 15 } 16 17 public void setName(String name) { 18 this.name = name; 19 } 20 21 public double getMoney() { 22 return money; 23 } 24 25 public void setMoney(double money) { 26 this.money = money; 27 } 28 29 @Override 30 public String toString() { 31 return "Topperformer{" + 32 "name='" + name + '\'' + 33 ", money=" + money + 34 '}'; 35 } 36 }Topperformer
1 import java.math.BigDecimal; 2 import java.math.RoundingMode; 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.stream.Stream; 6 public class StreamDemo04 { 7 public static double allMoney ; 8 public static double allMoney2 ; // 2个部门去掉最高工资,最低工资的总和 9 public static void main(String[] args) { 10 List<Employee> one = new ArrayList<>(); 11 one.add(new Employee("猪八戒",'男',30000 , 25000, null)); 12 one.add(new Employee("孙悟空",'男',25000 , 1000, "顶撞上司")); 13 one.add(new Employee("沙僧",'男',20000 , 20000, null)); 14 one.add(new Employee("小白龙",'男',20000 , 25000, null)); 15 16 List<Employee> two = new ArrayList<>(); 17 two.add(new Employee("武松",'男',15000 , 9000, null)); 18 two.add(new Employee("李逵",'男',20000 , 10000, null)); 19 two.add(new Employee("西门庆",'男',50000 , 100000, "被打")); 20 two.add(new Employee("潘金莲",'女',3500 , 1000, "被打")); 21 two.add(new Employee("武大郎",'女',20000 , 0, "下毒")); 22 23 // 1、开发一部的最高工资的员工。(API) 24 // 指定大小规则了 25 // Employee e = one.stream().max((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus())) 26 // .get(); 27 // System.out.println(e); 28 Topperformer t = one.stream().max((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus())) 29 .map(e -> new Topperformer(e.getName(), e.getSalary() + e.getBonus())).get(); 30 System.out.println(t); 31 32 // 2、统计平均工资,去掉最高工资和最低工资 33 one.stream().sorted((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus())) 34 .skip(1).limit(one.size() - 2).forEach(e -> { 35 // 求出总和:剩余员工的工资总和 36 allMoney += (e.getSalary() + e.getBonus()); 37 }); 38 System.out.println("开发一部的平均工资是:" + allMoney / (one.size() - 2)); 39 40 // 3、合并2个集合流,再统计 41 Stream<Employee> s1 = one.stream(); 42 Stream<Employee> s2 = two.stream(); 43 Stream<Employee> s3 = Stream.concat(s1 , s2); 44 s3.sorted((e1, e2) -> Double.compare(e1.getSalary() + e1.getBonus(), e2.getSalary() + e2.getBonus())) 45 .skip(1).limit(one.size() + two.size() - 2).forEach(e -> { 46 // 求出总和:剩余员工的工资总和 47 allMoney2 += (e.getSalary() + e.getBonus()); 48 }); 49 50 // BigDecimal 51 BigDecimal a = BigDecimal.valueOf(allMoney2); 52 BigDecimal b = BigDecimal.valueOf(one.size() + two.size() - 2); 53 System.out.println("开发部的平均工资是:" + a.divide(b,2, RoundingMode.HALF_UP)); 54 } 55 }View Code
1 package com.maofugui.stream; 2 3 import java.math.BigDecimal; 4 import java.math.RoundingMode; 5 import java.util.ArrayList; 6 import java.util.Comparator; 7 import java.util.List; 8 import java.util.function.Consumer; 9 import java.util.stream.Stream; 10 11 public class StreamDemo04 { 12 public static double sunMoney1;//存储开发一部的平均工资 13 public static double sunMoney2;//存储开发二部的平均工资 14 public static double sunMoney3;//存储开发一、二部的平均工资 15 public static void main(String[] args) { 16 List<Employee> one = new ArrayList<>(); 17 one.add(new Employee("猪八戒", '男', 30000, 25000, null)); 18 one.add(new Employee("孙悟空", '男', 25000, 1000, "顶撞上司")); 19 one.add(new Employee("沙僧", '男', 20000, 20000, null)); 20 one.add(new Employee("小白龙", '男', 20000, 25000, null)); 21 22 List<Employee> two = new ArrayList<>(); 23 two.add(new Employee("武松", '男', 15000, 9000, null)); 24 two.add(new Employee("李逵", '男', 20000, 10000, null)); 25 two.add(new Employee("西门庆", '男', 50000, 100000, "被打")); 26 two.add(new Employee("潘金莲", '女', 3500, 1000, "被打")); 27 two.add(new Employee("武大郎", '女', 20000, 0, "下毒")); 28 29 //筛选两个部门的最高工资的员工信息并进行封装 30 Employee e1 = one.stream().max((o1, o2) -> Double.compare(o1.getSalary() + o1.getBonus(), o2.getSalary() + o2.getBonus())).get(); 31 Topperformer te1 = new Topperformer(e1.getName(),e1.getSalary()+e1.getBonus()); 32 System.out.println(te1); 33 Employee e2 = two.stream().max((o1, o2) -> Double.compare(o1.getSalary() + o1.getBonus(), o2.getSalary() + o2.getBonus())).get(); 34 Topperformer te2 = new Topperformer(e2.getName(),e2.getSalary()+e2.getBonus()); 35 System.out.println(te2); 36 37 //分别计算出2个部门去掉最高工资和最低工资的平均月收入 38 //去掉最高工资和最低工资后的 39 Stream<Employee> e1s = one.stream().sorted((Employee o1, Employee o2) -> Double.compare(o1.getSalary() + o1.getBonus(), o2.getSalary() + o2.getBonus())) 40 .skip(1).limit(one.size() - 2); 41 //e1s.forEach(employee -> System.out.println(employee)); 42 System.out.println("-------------------"); 43 Stream<Employee> e2s = two.stream().sorted((Employee o1, Employee o2) -> Double.compare(o1.getSalary() + o1.getBonus(), o2.getSalary() + o2.getBonus())) 44 .skip(1).limit(two.size() - 2); 45 //e2s.forEach(employee -> System.out.println(employee)); 46 47 //计算总和 48 e1s.forEach((Employee employee) -> { 49 sunMoney1 += (employee.getSalary() + employee.getBonus()); 50 }); 51 System.out.println("开发一部的平均工资:" + sunMoney1 / (one.size()-2)); 52 53 e2s.forEach((Employee employee) -> { 54 sunMoney2 += (employee.getSalary() + employee.getBonus()); 55 }); 56 System.out.println("开发二部的平均工资:" + sunMoney2 / (two.size()-2)); 57 58 //统计2个开发部门整体的平均工资 59 Stream<Employee> s1 = one.stream(); 60 Stream<Employee> s2 = two.stream(); 61 Stream<Employee> s3 = Stream.concat(s1, s2); 62 Stream<Employee> s4 = s3.sorted((e11, e22) -> Double.compare(e11.getSalary() + e11.getBonus(), e22.getSalary() + e22.getBonus())).skip(1) 63 .limit(one.size() + two.size() - 2); 64 s4.forEach(employee -> sunMoney3 += (employee.getSalary()+employee.getSalary())); 65 System.out.println("开发部的平均工资:" + sunMoney3 / (one.size()+two.size()-2)); 66 67 //精度运算 68 BigDecimal sum1 = BigDecimal.valueOf(sunMoney3); 69 BigDecimal num1 = BigDecimal.valueOf(one.size()+two.size()-2); 70 System.out.println("开发部的平均工资:" + sum1.divide(num1, 2, RoundingMode.CEILING)); 71 } 72 }View Code自己写的
7、收集Stream流的作用
Stream流是操作集合/数组的手段
操作的结果数据最终要恢复到集合或者数组中去
1 package com.itheima.d2_stream; 2 3 import java.util.*; 4 import java.util.function.IntFunction; 5 import java.util.stream.Collectors; 6 import java.util.stream.Stream; 7 8 /** 9 目标:收集Stream流的数据到 集合或者数组中去。 10 */ 11 public class StreamDemo05 { 12 public static void main(String[] args) { 13 List<String> list = new ArrayList<>(); 14 list.add("张无忌"); 15 list.add("周芷若"); 16 list.add("赵敏"); 17 list.add("张强"); 18 list.add("张三丰"); 19 list.add("张三丰"); 20 21 Stream<String> s1 = list.stream().filter(s -> s.startsWith("张")); 22 List<String> zhangList = s1.collect(Collectors.toList()); // 可变集合 23 zhangList.add("java1"); 24 System.out.println(zhangList); 25 26 // List<String> list1 = s1.toList(); // 得到不可变集合 27 // list1.add("java"); 28 // System.out.println(list1); 29 30 // 注意注意注意:“流只能使用一次” 31 Stream<String> s2 = list.stream().filter(s -> s.startsWith("张")); 32 Set<String> zhangSet = s2.collect(Collectors.toSet()); 33 System.out.println(zhangSet); 34 35 Stream<String> s3 = list.stream().filter(s -> s.startsWith("张")); 36 // Object[] arrs = s3.toArray(); 37 String[] arrs = s3.toArray(String[]::new); // 可以不管,拓展一下思维!! 38 System.out.println("Arrays数组内容:" + Arrays.toString(arrs)); 39 40 } 41 }收集Stream流
第三节 异常
1、异常是什么?
异常是代码在编译或者执行的过程中可能出现的错误
2、异常分为几类
编译时异常、运行时异常
编译时异常:没有继承RuntimeException的异常,编译阶段就会出错
运行时异常:继承自RuntimeException的异常或其子类,编译阶段不报错,运行可能报错
3、学习异常的目的
避免异常的出现,同时处理可能出现的异常,让代码更稳健
=====================================================================================
===================================================================================================
1 package com.itheima.d3_exception; 2 3 /** 4 目标:异常的概念和体系。 5 6 什么是异常? 7 异常是程序在"编译"或者"执行"的过程中可能出现的问题。 8 异常是应该尽量提前避免的。 9 异常可能也是无法做到绝对避免的,异常可能有太多情况了,开发中只能提前干预!! 10 异常一旦出现了,如果没有提前处理,程序就会退出JVM虚拟机而终止,开发中异常是需要提前处理的。 11 12 研究异常并且避免异常,然后提前处理异常,体现的是程序的安全, 健壮性!!! 13 Java会为常见的代码异常都设计一个类来代表。 14 15 异常的体系: 16 Java中异常继承的根类是:Throwable。 17 18 Throwable(根类,不是异常类) 19 / \ 20 Error Exception(异常,需要研究和处理) 21 / \ 22 编译时异常 RuntimeException(运行时异常) 23 24 25 Error : 错误的意思,严重错误Error,无法通过处理的错误,一旦出现,程序员无能为力了, 26 只能重启系统,优化项目。 27 比如内存奔溃,JVM本身的奔溃。这个程序员无需理会。 28 29 Exception:才是异常类,它才是开发中代码在编译或者执行的过程中可能出现的错误, 30 它是需要提前处理的。以便程序更健壮! 31 32 Exception异常的分类: 33 1.编译时异常:继承自Exception的异常或者其子类,编译阶段就会报错, 34 必须程序员处理的。否则代码编译就不能通过!! 35 36 2.运行时异常: 继承自RuntimeException的异常或者其子类,编译阶段是不会出错的,它是在 37 运行时阶段可能出现,运行时异常可以处理也可以不处理,编译阶段是不会出错的, 38 但是运行阶段可能出现,还是建议提前处理!! 39 小结: 40 异常是程序在编译或者运行的过程中可能出现的错误!! 41 异常分为2类:编译时异常,运行时异常。 42 -- 编译时异常:继承了Exception,编译阶段就报错,必须处理,否则代码不通过。 43 -- 运行时异常:继承了RuntimeException,编译阶段不会报错,运行时才可能出现。 44 异常一旦真的出现,程序会终止,所以要研究异常,避免异常,处理异常,程序更健壮!! 45 */ 46 public class ExceptionDemo { 47 public static void main(String[] args) { 48 int[] arr = {10, 20, 40}; 49 System.out.println(arr[0]); 50 System.out.println(arr[1]); 51 System.out.println(arr[2]); 52 System.out.println(arr[3]); 53 System.out.println("-----------程序截止---------"); 54 } 55 }View Code
4、常见运行时异常
1 package com.itheima.d4_exception_runtimeException; 2 /** 3 拓展: 常见的运行时异常。(面试题) 4 运行时异常的概念: 5 继承自RuntimeException的异常或者其子类, 6 编译阶段是不会出错的,它是在运行时阶段可能出现的错误, 7 运行时异常编译阶段可以处理也可以不处理,代码编译都能通过!! 8 9 1.数组索引越界异常: ArrayIndexOutOfBoundsException。 10 2.空指针异常 : NullPointerException。 11 直接输出没有问题。但是调用空指针的变量的功能就会报错!! 12 3.类型转换异常:ClassCastException。 13 4.迭代器遍历没有此元素异常:NoSuchElementException。 14 5.数学操作异常:ArithmeticException。 15 6.数字转换异常: NumberFormatException。 16 17 小结: 18 运行时异常继承了RuntimeException ,编译阶段不报错,运行时才可能会出现错误! 19 */ 20 public class ExceptionDemo { 21 public static void main(String[] args) { 22 System.out.println("程序开始。。。。。。"); 23 /** 1.数组索引越界异常: ArrayIndexOutOfBoundsException。*/ 24 int[] arr = {1, 2, 3}; 25 System.out.println(arr[2]); 26 // System.out.println(arr[3]); // 运行出错,程序终止 27 28 /** 2.空指针异常 : NullPointerException。直接输出没有问题。但是调用空指针的变量的功能就会报错!! */ 29 String name = null; 30 System.out.println(name); // null 31 // System.out.println(name.length()); // 运行出错,程序终止 32 33 /** 3.类型转换异常:ClassCastException。 */ 34 Object o = 23; 35 // String s = (String) o; // 运行出错,程序终止 36 37 /** 5.数学操作异常:ArithmeticException。 */ 38 //int c = 10 / 0; 39 40 /** 6.数字转换异常: NumberFormatException。 */ 41 //String number = "23"; 42 String number = "23aabbc"; 43 Integer it = Integer.valueOf(number); // 运行出错,程序终止 44 System.out.println(it + 1); 45 46 System.out.println("程序结束。。。。。"); 47 } 48 }View Code
5、常见编译时异常的特点
编译时异常:没有继承RuntimeException,继承自Exception的异常或者其子类
编译阶段报错,必须处理,否则代码不通过
6、默认异常处理机制
默认的异常处理机制并不好,一旦真的出现异常,程序立即死亡。
1 package com.itheima.d6_exception_default; 2 /** 3 目标:异常的产生默认的处理过程解析。(自动处理的过程!) 4 (1)默认会在出现异常的代码那里自动的创建一个异常对象:ArithmeticException。 5 (2)异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机。 6 (3)虚拟机接收到异常对象后,先在控制台直接输出异常栈信息数据。 7 (4)直接从当前执行的异常点干掉当前程序。 8 (5)后续代码没有机会执行了,因为程序已经死亡。 9 10 小结: 11 异常一旦出现,会自动创建异常对象,最终抛出给虚拟机,虚拟机 12 只要收到异常,就直接输出异常信息,干掉程序!! 13 14 默认的异常处理机制并不好,一旦真的出现异常,程序立即死亡! 15 */ 16 public class ExceptionDemo { 17 public static void main(String[] args) { 18 System.out.println("程序开始。。。。。。。。。。"); 19 chu(10, 0); 20 System.out.println("程序结束。。。。。。。。。。"); 21 } 22 23 public static void chu(int a , int b){ 24 System.out.println(a); 25 System.out.println(b); 26 int c = a / b; 27 System.out.println(c); 28 } 29 }默认异常处理
7、编译时异常的处理机制
===============================================================
1 package com.itheima.d7_exception_handle; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.InputStream; 6 import java.text.ParseException; 7 import java.text.SimpleDateFormat; 8 import java.util.Date; 9 10 /** 11 目标:编译时异常的处理方式一。 12 13 编译时异常:编译阶段就会报错,一定需要程序员处理的,否则代码无法通过!! 14 15 抛出异常格式: 16 方法 throws 异常1 , 异常2 , ..{ 17 18 } 19 建议抛出异常的方式:代表可以抛出一切异常, 20 方法 throws Exception{ 21 22 } 23 24 方式一: 25 在出现编译时异常的地方层层把异常抛出去给调用者,调用者最终抛出给JVM虚拟机。 26 JVM虚拟机输出异常信息,直接干掉程序,这种方式与默认方式是一样的。 27 虽然可以解决代码编译时的错误,但是一旦运行时真的出现异常,程序还是会立即死亡! 28 这种方式并不好! 29 30 小结: 31 方式一出现异常层层跑出给虚拟机,最终程序如果真的出现异常,程序还是立即死亡!这种方式不好! 32 33 */ 34 public class ExceptionDemo01 { 35 36 // public static void main(String[] args) throws ParseException, FileNotFoundException { 37 // System.out.println("程序开始。。。。。"); 38 // parseTime("2011-11-11 11:11:11"); 39 // System.out.println("程序结束。。。。。"); 40 // } 41 // 42 // public static void parseTime(String date) throws ParseException, FileNotFoundException { 43 // SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss"); 44 // Date d = sdf.parse(date); 45 // System.out.println(d); 46 // 47 // InputStream is = new FileInputStream("E:/meinv.jpg"); 48 // } 49 50 public static void main(String[] args) throws Exception { 51 System.out.println("程序开始。。。。。"); 52 parseTime("2011-11-11 11:11:11"); 53 System.out.println("程序结束。。。。。"); 54 } 55 56 public static void parseTime(String date) throws Exception { 57 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 58 Date d = sdf.parse(date); 59 System.out.println(d); 60 61 InputStream is = new FileInputStream("E:/meinv.jpg"); 62 } 63 64 }View Code
==============================================================
1 package com.itheima.d7_exception_handle; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.InputStream; 6 import java.text.ParseException; 7 import java.text.SimpleDateFormat; 8 import java.util.Date; 9 10 /** 11 目标:编译时异常的处理方式二。 12 13 方式二:在出现异常的地方自己处理,谁出现谁处理。 14 15 自己捕获异常和处理异常的格式:捕获处理 16 try{ 17 // 监视可能出现异常的代码! 18 }catch(异常类型1 变量){ 19 // 处理异常 20 }catch(异常类型2 变量){ 21 // 处理异常 22 }... 23 24 监视捕获处理异常企业级写法: 25 try{ 26 // 可能出现异常的代码! 27 }catch (Exception e){ 28 e.printStackTrace(); // 直接打印异常栈信息 29 } 30 Exception可以捕获处理一切异常类型! 31 32 小结: 33 第二种方式,可以处理异常,并且出现异常后代码也不会死亡。 34 这种方案还是可以的。 35 但是从理论上来说,这种方式不是最好的,上层调用者不能直接知道底层的执行情况! 36 37 */ 38 public class ExceptionDemo02 { 39 public static void main(String[] args) { 40 System.out.println("程序开始。。。。"); 41 parseTime("2011-11-11 11:11:11"); 42 System.out.println("程序结束。。。。"); 43 } 44 45 public static void parseTime(String date) { 46 try { 47 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss"); 48 Date d = sdf.parse(date); 49 System.out.println(d); 50 51 InputStream is = new FileInputStream("E:/meinv.jpg"); 52 } catch (Exception e) { 53 e.printStackTrace(); // 打印异常栈信息 54 } 55 } 56 57 58 // public static void parseTime(String date) { 59 // try { 60 // SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss"); 61 // Date d = sdf.parse(date); 62 // System.out.println(d); 63 // 64 // InputStream is = new FileInputStream("E:/meinv.jpg"); 65 // } catch (FileNotFoundException|ParseException e) { 66 // e.printStackTrace(); // 打印异常栈信息 67 // } 68 // } 69 70 // public static void parseTime(String date) { 71 // try { 72 // SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss"); 73 // Date d = sdf.parse(date); 74 // System.out.println(d); 75 // 76 // InputStream is = new FileInputStream("E:/meinv.jpg"); 77 // } catch (FileNotFoundException e) { 78 // e.printStackTrace(); // 打印异常栈信息 79 // } catch (ParseException e) { 80 // e.printStackTrace(); 81 // } 82 // } 83 84 // public static void parseTime(String date) { 85 // try { 86 // SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss"); 87 // Date d = sdf.parse(date); 88 // System.out.println(d); 89 // } catch (ParseException e) { 90 // // 解析出现问题 91 // System.out.println("出现了解析时间异常哦,走点心!!"); 92 // } 93 // 94 // try { 95 // InputStream is = new FileInputStream("E:/meinv.jpg"); 96 // } catch (FileNotFoundException e) { 97 // System.out.println("您的文件根本就没有啊,不要骗我哦!!"); 98 // } 99 // } 100 }编译异常处理方式2
==============================================================================================
1 package com.itheima.d7_exception_handle; 2 3 import java.io.FileInputStream; 4 import java.io.InputStream; 5 import java.text.ParseException; 6 import java.text.SimpleDateFormat; 7 import java.util.Date; 8 9 /** 10 目标:编译时异常的处理方式三。 11 12 方式三: 在出现异常的地方把异常一层一层的抛出给最外层调用者, 13 最外层调用者集中捕获处理!!(规范做法) 14 15 小结: 16 编译时异常的处理方式三:底层出现的异常抛出给最外层调用者集中捕获处理。 17 这种方案最外层调用者可以知道底层执行的情况,同时程序在出现异常后也不会立即死亡,这是 18 理论上最好的方案。 19 20 虽然异常有三种处理方式,但是开发中只要能解决你的问题,每种方式都又可能用到!! 21 */ 22 public class ExceptionDemo03 { 23 public static void main(String[] args) { 24 System.out.println("程序开始。。。。"); 25 try { 26 parseTime("2011-11-11 11:11:11"); 27 System.out.println("功能操作成功~~~"); 28 } catch (Exception e) { 29 e.printStackTrace(); 30 System.out.println("功能操作失败~~~"); 31 } 32 System.out.println("程序结束。。。。"); 33 } 34 35 public static void parseTime(String date) throws Exception { 36 SimpleDateFormat sdf = new SimpleDateFormat("yyyy、MM-dd HH:mm:ss"); 37 Date d = sdf.parse(date); 38 System.out.println(d); 39 40 InputStream is = new FileInputStream("D:/meinv.jpg"); 41 } 42 43 }编译异常处理方式3
异常处理的总结
在开发中按照规范来说第三种方式是最好的:底层的异常抛出去给最外层,最外层集中捕获处理
实际应用中,只要代码能够编译通过,并且功能能完成,那么每一种异常处理方式似乎也都是可以的。就是说能跑就行,管你怎么写的。
8、运行时异常处理方式
1 package com.itheima.d8_exception_handle_runtime; 2 3 /** 4 目标:运行时异常的处理机制。 5 6 可以不处理,编译阶段又不报错。 7 按照理论规则:建议还是处理,只需要在最外层捕获处理即可 8 */ 9 public class Test { 10 public static void main(String[] args) { 11 System.out.println("程序开始。。。。。。。。。。"); 12 try { 13 chu(10, 0); 14 } catch (Exception e) { 15 e.printStackTrace(); 16 } 17 System.out.println("程序结束。。。。。。。。。。"); 18 } 19 20 public static void chu(int a , int b) { // throws RuntimeException{ 21 System.out.println(a); 22 System.out.println(b); 23 int c = a / b; 24 System.out.println(c); 25 } 26 }运行时处理异常Test
9、异常处理使代码更稳健的案例
1 package com.itheima.d8_exception_handle_runtime; 2 3 import java.util.Scanner; 4 5 /** 6 需求:需要输入一个合法的价格为止 要求价格大于 0 7 */ 8 public class Test2 { 9 public static void main(String[] args) { 10 Scanner sc = new Scanner(System.in); 11 while (true) { 12 try { 13 System.out.println("请您输入合法的价格:"); 14 String priceStr = sc.nextLine(); 15 // 转换成double类型的价格 16 double price = Double.valueOf(priceStr); 17 18 // 判断价格是否大于 0 19 if(price > 0) { 20 System.out.println("定价:" + price); 21 break; 22 }else { 23 System.out.println("价格必须是正数~~~"); 24 } 25 } catch (Exception e) { 26 System.out.println("用户输入的数据有毛病,请您输入合法的数值,建议为正数~~"); 27 } 28 } 29 } 30 }老师写的代码
1 package com.maofugui.exception; 2 3 import java.util.Scanner; 4 import java.util.regex.Pattern; 5 6 public class ExceptionDemo02 { 7 public static void main(String[] args){ 8 9 String regex = "[+]?\\d+\\.?\\d?"; 10 // Pattern pattern = Pattern.compile(regex); 11 Scanner sc = new Scanner(System.in); 12 while (true) { 13 14 System.out.println("请输入一个合理的价格:"); 15 String price = sc.nextLine(); 16 boolean b = price.matches(regex); 17 if(b){ 18 System.out.println("输入正确"); 19 break; 20 }else { 21 System.out.println("输入错误,请重新输入"); 22 } 23 } 24 } 25 }使用正则表达式的代码
10、自定义异常
1 package com.itheima.d9_exception_custom; 2 3 /** 4 自定义的编译时异常 5 1、继承Exception 6 2、重写构造器 7 */ 8 public class ItheimaAgeIlleagalException extends Exception{ 9 public ItheimaAgeIlleagalException() { 10 } 11 12 public ItheimaAgeIlleagalException(String message) { 13 super(message); 14 } 15 }ItheimaAgeIlleagalException
1 package com.itheima.d9_exception_custom; 2 3 /** 4 自定义的编译时异常 5 1、继承RuntimeException 6 2、重写构造器 7 */ 8 public class ItheimaAgeIlleagalRuntimeException extends RuntimeException{ 9 public ItheimaAgeIlleagalRuntimeException() { 10 } 11 12 public ItheimaAgeIlleagalRuntimeException(String message) { 13 super(message); 14 } 15 }ItheimaAgeIlleagalRuntimeException
1 package com.itheima.d9_exception_custom; 2 /** 3 目标:自定义异常(了解) 4 5 引入:Java已经为开发中可能出现的异常都设计了一个类来代表. 6 但是实际开发中,异常可能有无数种情况,Java无法为 7 这个世界上所有的异常都定义一个代表类。 8 假如一个企业如果想为自己认为的某种业务问题定义成一个异常 9 就需要自己来自定义异常类. 10 11 需求:认为年龄小于0岁,大于200岁就是一个异常。 12 13 自定义异常: 14 自定义编译时异常. 15 a.定义一个异常类继承Exception. 16 b.重写构造器。 17 c.在出现异常的地方用throw new 自定义对象抛出! 18 编译时异常是编译阶段就报错,提醒更加强烈,一定需要处理!! 19 20 自定义运行时异常. 21 a.定义一个异常类继承RuntimeException. 22 b.重写构造器。 23 c.在出现异常的地方用throw new 自定义对象抛出! 24 提醒不强烈,编译阶段不报错!!运行时才可能出现!! 25 26 */ 27 public class ExceptionDemo { 28 public static void main(String[] args) { 29 // try { 30 // checkAge(-34); 31 // } catch (ItheimaAgeIlleagalException e) { 32 // e.printStackTrace(); 33 // } 34 35 try { 36 checkAge2(-23); 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 } 41 42 public static void checkAge2(int age) { 43 if(age < 0 || age > 200){ 44 // 抛出去一个异常对象给调用者 45 // throw :在方法内部直接创建一个异常对象,并从此点抛出 46 // throws : 用在方法申明上的,抛出方法内部的异常 47 throw new ItheimaAgeIlleagalRuntimeException(age + " is illeagal!"); 48 }else { 49 System.out.println("年龄合法:推荐商品给其购买~~"); 50 } 51 } 52 53 public static void checkAge(int age) throws ItheimaAgeIlleagalException { 54 if(age < 0 || age > 200){ 55 // 抛出去一个异常对象给调用者 56 // throw :在方法内部直接创建一个异常对象,并从此点抛出 57 // throws : 用在方法申明上的,抛出方法内部的异常 58 throw new ItheimaAgeIlleagalException(age + " is illeagal!"); 59 }else { 60 System.out.println("年龄合法:推荐商品给其购买~~"); 61 } 62 } 63 }ExceptionDemo
标签:JAVA,进阶,Stream,--,System,println,异常,public,out 来源: https://www.cnblogs.com/Flower--Dance/p/16654682.html