栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JavaSE进阶、Stream流、异常处理和日志框架

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaSE进阶、Stream流、异常处理和日志框架

目录

一、Stream流

1、Stream流概述

2、stream流的思想

3、Stream流的三类方法

获取Stream流方法

中间方法

终结方法

 4、Stream流的综合案例

5、收集Stream流

 二、异常处理

1、异常概念

 2、异常体系

 常见运行时异常

 常见编译时异常

3、异常的默认处理流程  

4、编译时异常的处理机制

异常处理方式一、throws

异常处理方式二、try...catch...

 异常处理方式三、前两者结合

 5、运行时异常的处理机制

6、异常处理案例

7、自定义异常

 自定义编译时异常

自定义运行时异常

三、日志框架

1、日志概念

2、以前记录日志的形式

 3、日志技术

 4、日志技术体系

5、Logback概述

 6、Logback开发步骤

7、设置日志级别选择输出日志的内容


 

一、Stream流

1、Stream流概述

目的:用于简化集合和数组操作的API

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class StreamDemo {
    public static void main(String[] args) {
        //Stream流初体验
        List names = new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","赵成功","周芷若","张明");
        System.out.println(names);

        //1、找出以张开头的人
        List zhanglist = new ArrayList<>();
        for (String name : names) {
            if (name.startsWith("张")){
                zhanglist.add(name);
            }
        }
        System.out.println(zhanglist);

        //2、找出姓张并且只有三个字的人
        List zhangtherelist = new ArrayList<>();
        for (String s : zhanglist) {
            if (s.length() == 3){
                zhangtherelist.add(s);
            }
        }
        System.out.println(zhangtherelist);

        //使用stream流一步实现,支持链式运算
        //集合names使用stream流调用stream流的filter方法
        //filter方法表示过滤,内部写过滤条件,过滤出来的元素就存在这个流中
        //s表示 names中的所有元素,筛选出names中以”张“开头且只有三个字的元素,再通过forEach遍历这个流
        names.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));


    }
}

2、stream流的思想

stream流就相当于一个流水线的传送带,依次过滤元素。

3、Stream流的三类方法

获取Stream流方法

public static void main(String[] args) {
        
        Collection collection = new ArrayList<>();
        Stream s = collection.stream();

        
        Map maps = new HashMap<>();
        //键流
        Stream s1 = maps.keySet().stream();
        //值流
        Stream s2 = maps.values().stream();
        //键值对
        Stream> s3 = maps.entrySet().stream();

        
        String[] str = {"ad","ad","awd"};
        //方法一
        Stream stream = Arrays.stream(str);
        //方法二
        Stream str1 = Stream.of(str);

    }

中间方法

public static void main(String[] args) {
        List names = new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","赵成功","周芷若","张明");

        //1、filter 是接口抽象方法 重写
        names.stream().filter(new Predicate() {
            @Override
            public boolean test(String s) {
                return s.startsWith("张");
            }
        }).forEach(new Consumer() {
            //forEach遍历同样也是创建匿名对象,重写方法
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //简化
        //流水线开始     .                   执行流水线     .      结束流水线
        //names.stream().filter( s ->  s.startsWith("张")).forEach(s -> System.out.println(s));
        //继续简化 ::方法引用                当lambda表达式样式为  s 参数      相等     s入参
        names.stream().filter( s ->  s.startsWith("张")).forEach(System.out::println);


        //2、count() 获取过滤后的个数 终结方法
        long size = names.stream().filter(s -> s.length() == 3).count();
        System.out.println(size);

        //3、limit 取前几个元素
        names.stream().filter(s -> s.startsWith("张")).limit(2).forEach(System.out::println);

        //4、跳过前几个
        names.stream().filter(s -> s.startsWith("张")).skip(2).forEach(System.out::println);

        //5、Map加工方法
        //相当于对流水线上的瓶子,盖盖子,进一步加工
        names.stream().map(new Function() {
            //map也能够对数据进行遍历,每遍历到一个元素s就会传给apply进行加工
            @Override
            public String apply(String s) {
                return "黑马的" + s;
            }
        });
        //简化            原材料   加工后成品
        names.stream().map(s ->"黑马的" + s).forEach(System.out::println);
        //全部加工成学生对象
        //names.stream().map(s -> new Student(s)).forEach(System.out::println);
        //再简化 构造器引用
        names.stream().map(Student::new).forEach(System.out::println);

        //6、合并流
        Stream s1 = names.stream().filter(s -> s.startsWith("张"));
        Stream s2 = Stream.of("java","python");
        //s3流的类型必须是s2和s1的父类
        Stream s3 = Stream.concat(s1, s2);
        s3.forEach(System.out::println);

        //7、去重复
        s3.distinct().forEach(System.out::println);
    }

终结方法

public T get()       获取流水线上的元素

 终结方法后流不可以继续使用,非终结方法会返回新的流,支持链式编程。

 4、Stream流的综合案例

import java.util.*;
import java.util.stream.Stream;

public class CompanyTest {
    //静态变量所有人共享
    public static double allMoney;

    public static void main(String[] args) {
        //一部
        List performs1 = new ArrayList<>();

        performs1.add(new Perform("李华", '男', 4090.0, 6060.0));
        performs1.add(new Perform("博罗", '男', 7050.0, 3300.0));
        performs1.add(new Perform("塞拉", '女', 520.0, 6090.0));
        performs1.add(new Perform("李华", '男', 4000.0, 6010.0));

        //二部
        List performs2 = new ArrayList<>();
        performs2.add(new Perform("兆维", '男', 2000.0, 1010.0));
        performs2.add(new Perform("安特", '男', 2340.0, 1976.0));
        performs2.add(new Perform("威威", '男', 9760.0, 410.0));
        performs2.add(new Perform("安娜", '女', 5060.0, 1221.0));
        performs2.add(new Perform("吉娜", '女', 4500.0, 1089.0));


        //获取一部优秀员工
        //只有一个对象 用get获取
        //Perform p1 = performs1.stream().max(((o1, o2) -> Double.compare((o1.getReward()+o1.getSalary()),(o2.getReward()+o2.getSalary())))).get();
        //直接使用map加工,将获取到的优秀员工直接加工成优秀员工对象
        Topperform t1 = performs1.stream().max(((o1, o2) -> Double.compare((o1.getReward()+o1.getSalary()),(o2.getReward()+o2.getSalary()))))
                .map(perform -> new Topperform(perform.getName(), (perform.getReward())+perform.getSalary())).get();
        //获取并封装二部优秀员工
        Topperform t2 = performs2.stream().max(((o1, o2) -> Double.compare((o1.getReward()+o1.getSalary()),(o2.getReward()+o2.getSalary()))))
                .map(perform -> new Topperform(perform.getName(), (perform.getReward())+perform.getSalary())).get();


        //统计平均工资,掐头去尾
        performs1.stream().sorted((o1, o2) -> Double.compare((o1.getReward()+o1.getSalary()),(o2.getReward()+o2.getSalary())))
                .skip(1).limit(performs1.size() - 2).forEach(perform -> {
                    //剩余员工工资总和
                    allMoney += (perform.getReward() + perform.getSalary());
                });
        //1部的平均工资
        System.out.println("1部工资" + allMoney / (performs1.size() - 2));

    }
}

5、收集Stream流

public static void main(String[] args) {
        List names = new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","赵成功","周芷若","张明");

        //注意:流只能使用一次,收集之后就不能再操作
        //收集成集合
        Stream s1 = names.stream().filter(s -> s.startsWith("张"));
        List Zhanglist = s1.collect(Collectors.toList());

        //可以直接转成List集合,但是得到的是一个不可变集合
        List list = s1.toList();

        //转成数组
        Stream s2 = names.stream().filter(s -> s.startsWith("张"));
        Object[] objects = s2.toArray();
        System.out.println(Arrays.toString(objects));
    }

 二、异常处理

1、异常概念

 2、异常体系

 常见运行时异常

 常见编译时异常

3、异常的默认处理流程  

默认处理流程: 默认会在出现异常的代码那里自动创建一个异常对象,异常会从方法中出现的地方  chu(10,0)抛给调用者,调用者最终抛给JVM虚拟机,虚拟机收到异常对象后,先在控制台直接输出异常栈信息数据,然后直接从当前执行的异常点干掉当前程序。程序直接死亡。

4、编译时异常的处理机制

异常处理方式一、throws

可以抛多个异常但最终能够抛出去的只有一个,谁先出异常就先抛谁。

 

public static void main(String[] args) throws FileNotFoundException, ParseException {
        System.out.println("程序开始");
        //下面抛到main方法,main方法再抛
        parseTime("2010-11-11-11");
    }
    
    //不论抛出几个异常真正被抛出去的只有一个
    private static void parseTime(String s) throws FileNotFoundException, ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
        //一层一层往上抛
        Date d = sdf.parse(s);

        InputStream is  = new FileInputStream("E:/mm.jpg");
    }
    //规范格式
    //不论有多少异常,Exception都能涵盖,不用一个一个异常写
    private static void parseTime(String s) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
        //一层一层往上抛
        Date d = sdf.parse(s);

        InputStream is  = new FileInputStream("E:/mm.jpg");
    }

异常处理方式二、try...catch...

拦截捕获异常并自行处理,防止程序死亡。

如果同时捕获多个异常,它只会显示先报错的异常,其他的异常信息不显示

private static void parseTime(String s) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
            Date d = sdf.parse(s);
            InputStream s1 = new FileInputStream("E:/we.jpg");
        } catch (ParseException e) {
            //解析出现问题处理
            //System.out.println("出现解析时间异常");
            //默认使用官方的打印方式
            e.printStackTrace();  //打印异常栈信息
        } catch (FileNotFoundException e) {
            //能够捕获但不会打印异常信息
            //System.out.println("捕获第二个异常");
            e.printStackTrace();
        }

        //标准格式
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
            Date d = sdf.parse(s);
            InputStream s1 = new FileInputStream("E:/we.jpg");
        } catch (Exception e) {  
            //Exception捕获一切异常
           e.printStackTrace();
        }

    }

 异常处理方式三、前两者结合

将异常问题抛给调用者,调用者捕获异常进行解决

public static void main(String[] args){
        //调用者进行异常捕获处理
        try {
            System.out.println("程序开始");
            //下面抛到main方法,main方法再抛
            parseTime("2010-11-11-11");
            //功能操作成功
            System.out.println("程序结束");

        } catch (Exception e) {
            //功能操作失败
            e.printStackTrace();
        }
    }

    //底层将异常抛出
    private static void parseTime(String s) throws Exception{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM-dd HH:mm:ss");
            Date d = sdf.parse(s);
            InputStream s1 = new FileInputStream("E:/we.jpg");

    }

 5、运行时异常的处理机制

运行时异常可以不做处理,但一般建议处理防止程序死亡,不需要一层一层抛异常,他会默认自动向外抛异常,只需要在调用会报异常的地方进行try...catch异常捕获。

public static void main(String[] args){
        //只需要对他进行异常捕获,底层自动向外抛异常
        try {
            System.out.println("程序开始");
            //下面抛到main方法,main方法再抛
            parseTime("2010-11-11-11");
            //功能操作成功
            System.out.println("程序结束");

        } catch (Exception e) {
            //功能操作失败
            e.printStackTrace();
        }
    }

6、异常处理案例
public static void main(String[] args) {
//用户不断输入价格直到正确为止
        Scanner sc = new Scanner(System.in);
        while (true){
            try {
                System.out.println("请您输入价格:");
                //不要在死循环中输入double型数据,因为第一次没有接到数据后,他会不断接这个数据产生bug
                //double price = sc.nextDouble();
                //接一行数据,一定会接到
                String s = sc.nextLine();
                double price = Double.valueOf(s);
                if (price >= 0){
                    System.out.println("定价:" + price);
                    break;
                }else {
                    System.out.println("价格必须是正数");
                }
            } catch (Exception e) {
                System.out.println("用户输入有问题");
            }
        }
    }

7、自定义异常

 自定义编译时异常
public static void main(String[] args) {
        try {
            check(-32);
        } catch (ItheimaAgeIlleagalException e) {
            e.printStackTrace();
        }
    }

    //抛出异常
    private static void check(int age) throws ItheimaAgeIlleagalException {
        if (age < 0 || age > 200){
            //抛出一个异常对象,并提示异常错误
            //throw: 在方法内部创建一个异常对象,并从此点抛出
            //throws:用在方法声明上,抛出方法内部的异常
            throw new ItheimaAgeIlleagalException(age + "is illeagal");
        }else {
            System.out.println("年龄合法");
        }
    }


//定义异常类
public class ItheimaAgeIlleagalException extends Exception{
    //创建一个异常类继承 父异常,重写构造器
    public ItheimaAgeIlleagalException() {
    }

    //可以自定义异常信息
    public ItheimaAgeIlleagalException(String message) {
        super(message);
    }
}

自定义运行时异常
public static void main(String[] args) {
        try {
            //外层捕获异常
            check(-32);
        } catch (ItheimaAgeIlleagalException e) {
            e.printStackTrace();
        }
    }

    //默认会抛出异常
    private static void check(int age) {
        if (age < 0 || age > 200){
            throw new ItheimaAgeIlleagalException(age + "is illeagal");
        }else {
            System.out.println("年龄合法");
        }
    }


//定义异常类
public class ItheimaAgeIlleagalException extends RunTimeException{
    //创建一个异常类继承 父异常,重写构造器
    public ItheimaAgeIlleagalException() {
    }

    //可以自定义异常信息
    public ItheimaAgeIlleagalException(String message) {
        super(message);
    }
}

三、日志框架

1、日志概念

日志就相当于是日记,记录程序运行中的信息。

2、以前记录日志的形式

 3、日志技术

 4、日志技术体系

5、Logback概述

目前logback分为三个模块:logback-core、logback-classic、logback-access。目前需要属于的是前两个,logback-access模块与Tomcat和Jetty等Servlet容器集成,以提供HTTP访问日志功能。

 6、Logback开发步骤

  导入依赖库的方法,将所有jar包选中,右键选择然后 OK。

 

public class Test {
    //创建logback日志对象,代表日志技术
    //快速搭建Logback日志框架,记录程序的执行情况到控制台
    //将当前类文件加载进日志中
    public static final Logger LOGGER = LoggerFactory.getLogger("Test.class");

    public static void main(String[] args) {
        try {
            LOGGER.debug("main开始执行");
            LOGGER.info("我开始记录第二行");
            int a = 10;
            int b = 0;
            LOGGER.trace("a=" + a);
            LOGGER.trace("b=" + b);

            System.out.println(a / b);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("功能出现异常" + e);
        }
    }
}

7、设置日志级别选择输出日志的内容

ERROR 错误级别、WARN 警告级别、INFO关键信息级别、DEBUG 调试级别、TRACE路径跟踪级别

 注意只有代码中写了打印级别才能打印对应级别的错误信息

//声明打印级别
LOGGER.debug("main开始执行");
LOGGER.info("我开始记录第二行");

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1007638.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号