Java教程

JAVA进阶--不可变集合、Stream流、异常--2022年9月4日

本文主要是介绍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流、异常--2022年9月4日的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!