尚硅谷_初级_java8 新特性(666-692)

大处着眼,小处着手。

 (视频:尚硅谷:https://www.bilibili.com/video/BV1Kb411W75N?p=666)

目录

一:前言:

二:Lambda 表达式(使代码更简洁)

三:函数式(Functional)接口(Interface)

四:方法引用 与 构造器引用(用于替换 Lambda 表达式)

五:强大的 Stream API(对内存中数据操作)

六:Optional 类(最大化减少空指针异常)


一:前言:

               1)Java 8 最大的两个改变(2):
                            a:Lambda 表达式;
                            b:Stream API(并行流 / 串行流)


               2)接口增强(2):接口中 可以写 (默认)default 方法,静态方法。
                                     (java 8 中,Collection,List,Comparator 等接口,提供了丰富的默认方法。)
                            a:默认方法:由子类的对象调用,子类可以重写。
                            b:静态方法:由父类.静态方法名 调用,子类不能重写,子类对象不能调用。

public class Test_01 implements A {

    @Override
    public void a() {
        System.out.println("重写后的A");
    }
    
    public static void main(String[] args) {
        Test_01 test_01 = new Test_01();
        test_01.a();
        A.b();
        //重写后的 A
        //静态方法 b
    }
}

interface A {
    public default void a() {
        System.out.println("重写前的 a");
    }

    public static void b() {
        System.out.println("静态方法 b");
    }
}

               3)提供新的 时间 和 日期 API:(LocalDateTime();
               4)注解:(看 基础-注解 笔记)

                            a:可重复注解:
                            b:类型注解:

               5)容器底层变化:集合和map。
               6)方法引用:
               7)构造器引用 / 数组引用:
               8)函数式接口:
@FunctionalInterface
               9)Optional 类: 





 

二:Lambda 表达式(使代码更简洁)


               1)lambda介绍:
                            a:lambda 是一个匿名函数,我们可以将 Lambda 表达式,理解为是一段可以传递的代码,(将代码像数据一样传递)
                            b:使用它,可以写出更简洁,更灵活的代码。

               2)将来大数据 spark 底层有使用,java8 新特性,比如 Lambda 表达式。
               3)举例:

                            a:普通写法:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("我爱北京天安门");
    }
};
runnable.run();

                                 Lambda表达式:

Runnable runnable2 = () -> System.out.println("我爱北京故宫");
runnable2.run();


                            b:普通写法:

Comparator<Integer> integerComparator = new Comparator<Integer>() {
    @Override
    public int compare(Integer o1, Integer o2) {
        int compare = Integer.compare(o1, o2);
        return compare;
    }
};
int compare = integerComparator.compare(3, 2);
System.out.println(compare);

                                Lambda表达式写法:

Comparator<Integer> integerComparato2r = (o1, o2) -> Integer.compare(o1, o2);
int compare2 = integerComparato2r.compare(3, 2);
System.out.println(compare2);

                                 方法引用写法:

Comparator<Integer> integerComparator1 = Integer::compare;


               4)解释 lambda 表达式:
                            a:-> :Lambda 操作符/箭头操作符
                            b:左边:Lambda 形参列表

                                   -1.接口中,抽象方法的形参。其实就是,接口中,抽象方法的形参列表。
                                   -2.Lambda 表达式,参数类型可以省略。如果 Lambda 表达式 只有一个参数,其 () 也可以省略。
                                   -3.右边:Lambda 体:

                                         1.接口中,抽象方法的方法体。其实就是 抽象方法的 方法体。
                                         2.Lambda 体,应该使用 { } 包裹,如果 Lambda 表达式,只有一条语句
                                          (也有可能是 return 语句),则可以 省略 大括号 和 return 关键字。

                            c:以前用,匿名实现类 表示的方式 ,现在都可以用 Lambda 表达式来写。
                            d:Lambda 表达式 本质:就是一个函数式接口的实例。



               5)Lambda 表达式分类(6)
                            a:无参 无返回值:

Runnable runnable = () -> System.out.println("123");

                            b:有参 无返回值:

Consumer<String> con = (String s) -> {
    System.out.println("ss");
};
con.accept("张三");

                            c:数据类型可以省略,因为可以由编译器 推断得出,称为 “类型推断”

Consumer<String> con = (s) -> {
    System.out.println("ss");
};
con.accept("张三");

                            d:Lambda 表达式,若只需要一个参数,参数的小括号可以省略:

Consumer<String> con = s -> {
    System.out.println("ss");
};
con.accept("张三");

                            e:Lambda 表达式,需要两个或者以上的参数,多条语句执行,可以有返回值

Comparator<Integer> integerComparator = (o1, o2) -> {
    System.out.println(o1);
    System.out.println(o2);
    return Integer.compare(o1, o2);
};

                            f:Lambda 体只有一条语句时,return 或 大括号 都可以可以省略:

Comparator<Integer> integerComparator = (o1, o2) -> return Integer.compare(o1, o2);



               6)Lambda 表达式 本质:
                            a:作为 函数式 接口的实例,
                            b:函数式 接口 的特点就是,只有一个抽象方法。

                                    -1.如果在一个接口中,只声明一个抽象方法,此接口 称为 函数式接口。
                                    -2.接口使用 : @FunctionalInterface  修饰。


                            c:Lmabda 表达式 只能在 函数式接口中 使用。



 

三:函数式(Functional)接口(Interface)


               1)如果一个接口中,只包含 一个抽象方法,此接口,就称为,函数式接口。
               2)可以通过 Lambda 表达式,创建 函数式接口 的对象。
               3)@FunctionalInterface 注解 :接口上标注,说明此接口,是函数事接口,

                            a:不是函数式接口,报错,也可以起到检验是否是函数式接口的作用。

               4)Java 内置 ,四大核心 函数式接口:(参数类型      返回类型      用途
                            a:消费型接口:放一个参数,但是不返回。
                 Consumer<T>        T             void           void  accep(T t)。对类型为 T 的对象 应用操作。

    @Test
    public void test_01() {

        happyTime(22.2, new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("学习太累了,去花 " + aDouble + " 钱。");
            }
        });

        System.out.println("***********");

        happyTime(22.2, a1Double -> System.out.println("学习太累了,去花 " + a1Double + " 钱。"));

    }

    public void happyTime(Double dd, Consumer<Double> consumer) {
        consumer.accept(dd);
    }
    public static void main(String[] args) {
        TestConsumer.TestCon(22.2, aDouble -> {
            System.out.println(aDouble);
        });
    }
    public static void TestCon(double dd, Consumer<Double> consumer) {
        consumer.accept(dd);
    }


                            b:供给型接口:不给他参数,他都往回返。
                  Supplier<T>          无           T               T  get()。           返回类型为 T 类型,包含方法:

        Supplier<String> stringSupplier = () -> employee.getName();
        String s = stringSupplier.get();
        System.out.println(s);


                            c:函数型接口:放一个参数,返回一个参数。
                 Function<T,R>       T            R                R  apple(T t)。  对 类型 T 的对象应用操作,并返回 R 类型对象。

        Function<Double, Long> doubleLongFunction = o -> Math.round(o);

        Long apply = doubleLongFunction.apply(5.5);
        System.out.println(apply);

        Function<Integer, Employee> integerEmployeeFunction = o -> new Employee(o);

        Employee apply = integerEmployeeFunction.apply(19);

        System.out.println(apply);


                            d:断定型接口:放进一个参数,返回一个判断结果,(true/false)
                 Predicate<T>         T        Boolean          boolean  test(T t)。确定类型为 T 的对象,是否满足约束。

@Test
public void test_01() {

    List<String> strings = Arrays.asList("北京", "南京", "天津", "东京");

    List<String> j = filterString(strings, new Predicate<String>() {
        @Override
        public boolean test(String s) {
            return s.contains("京");
        }
    });
    System.out.println(j.toString());
}

public List<String> filterString(List<String> list, Predicate<String> predicate) {
    ArrayList<String> filterList = new ArrayList<>();
    for (String str : list) {
        if (predicate.test(str)) {
            filterList.add(str);
        }
    }
    return filterList;
}







 

四:方法引用、构造器引用、数组引用 (用于替换 Lambda 表达式)


               1)方法引用:
                            a:方法引用使用场景:
                                    -1.当要传递给 Lambda体 的操作,已经有实现的方法了,可以使用方法引用。
                                    -2.方法引用:可以看做是,Lambda 表达式,更深层次的表达。
                                    -3.换句话说:方法引用本质 就是 Lambda 表达式,也就是函数式接口的一个实例。
                                    -4.通过 方法的名字,来指向一个方法,可以认为是 Lambda 表达式 的一个语法糖。


                            b:要求:


                            b:使用格式:
                                    -1.类 / 对象  ::  方法名


                            c:具体分为 三种情况:

                                    -1.对象  ::  非静态方法:举例
                                                1.Lambda表达式 表示:

        Consumer<String> stringConsumer = o -> System.out.println(o);
        stringConsumer.accept("张三");

                                                     方法引用 表示:

        PrintStream stream = System.out;
        //对象 :: 方法名
        Consumer<String> stringConsumer2 = stream::println;
        stringConsumer2.accept("张三");

                                                2.Lambda表达式 表示:

        Supplier<String> stringSupplier = () -> employee.getName();
        String s = stringSupplier.get();
        System.out.println(s);

                                                    方法引用 表示:

        Supplier<String> stringSupplier2 = employee::getName;
        String s1 = stringSupplier.get();
        System.out.println(s1);


                                    -2.类  ::  静态方法
                                                1.Lambda表达式 表示:

        Comparator<Integer> integerComparator = (o1, o2) -> Integer.compare(o1, o2);
        int compare = integerComparator.compare(10, 20);
        System.out.println(compare);

                                                    方法引用 表示:

        Comparator<Integer> integerComparator1 = Integer::compare;
        int compare1 = integerComparator1.compare(10, 20);
        System.out.println(compare1);

                                                2.Lambda表达式 表示:

        Function<Double, Long> doubleLongFunction = o -> Math.round(o);

        Long apply = doubleLongFunction.apply(5.5);
        System.out.println(apply);

                                                   方法引用 表示:

        Function<Double, Long> doubleLongFunction2 = Math::round;

        Long apply2 = doubleLongFunction.apply(5.5);
        System.out.println(apply2);


                                    -3.类  ::  非静态方法


                            d:方法引用的使用要求:
                                    -1.要求接口中的  抽象方法的 形参列表 和 返回值类型,与 方法引用的 方法的 形参列表 和 返回值类型相同。



               4)构造器引用
                            d:构造器引用举例:
                                    -1.Lambda表达式 表示:

        Supplier<Employee> employeeSupplier = () -> new Employee();
        Employee employee = employeeSupplier.get();
        System.out.println(employee);

                                         构造器引用 表示:

        Supplier<Employee> employeeSupplier1 = Employee::new;
        Employee employee1 = employeeSupplier.get();
        System.out.println(employee);

                                    -2.Lambda表达式 表示:

        Function<Integer, Employee> integerEmployeeFunction = o -> new Employee(o);

        Employee apply = integerEmployeeFunction.apply(19);

        System.out.println(apply);

                                        构造器引用 表示:

        Function<Integer, Employee> integerEmployeeFunction2 = Employee::new;
        
        Employee apply1 = integerEmployeeFunction2.apply(18);
        System.out.println(apply1);


                            d:要求:
                                    -1.和方法引用类似:
                                            函数式接口的 抽象方法的 形参列表 和 构造器形参列表一致,
                                    -2.抽象方法的返回值类型 即为 构造器 所属的类的类型。


               4)数组引用:
                            a:介绍:如果把 数组 看做成为 一个 特殊的类,则写法 与 构造器引用 一致。
                            b:数组引用举例:

                                    -1.Lambda表达式 表示:

        Function<Integer, String[]> integerFunction = length -> new String[length];

        String[] apply = integerFunction.apply(10);

        for (String str : apply) {
            System.out.print(str+",");
        }

                                       方法引用 表示:

        Function<Integer, String[]> integerFunction1 = String[]::new;

        String[] apply1 = integerFunction1.apply(3);

        for (String str : apply1) {
            System.out.print(str+",");
        }







 

五:强大的 Stream API(对内存中数据操作)


               1)Strean 介绍
                            a:并行流:
                                    -1.就是将一个内容,分成多个数据块,并用不同的线程,分别处理每个数据块的流。
                                    -2.相比于串行流,并行流可以很大程度上提高程序的执行效率。
                            b:串行流:

               2)Stream 介绍
                            a:java 8 重要的改变:
                                    -1.Stream API 真正的把 函数式编程风格,引入到java 中,简化了对集合的操作,
                                    -2.可以执行复杂的 查找、过滤 和 映射数据 等操作。


                            b:为什么使用 Stream API:?
                                    -1.实际开发中,项目中多数数据源都来自 mysql,oracle等数据库,
                                    -2.但现在,数据源更多了,有 MongDB,Redis等,
                                    -3.而这些,NoSQL 的数据,就需要java 层面来处理了。


                            c:Stream 和 Collection 区别:
                                    -1.集合讲的数据的存储,与内存打交道。
                                    -1.Stream 讲的是计算,与cpu打交道。

                                    -2.Collection :

                                            1.是一种 静态的内存数据结构,主要是对数据的存储。
                                            2.主要是面向内存,存储到内存中。

                                    -2.而 Stream  :(数据渠道)
                                          1.是有关计算的,用于操作数据源 所生成的 元素序列。
                                          2.主要面向 CPU,通过 CPU 计算实现。


                            d:注意:
                                    -1.Stream 不会自己存储数据
                                    -2.Stream 不会改变源对象。相反,他们会返回一个,持有结果的新 Stream
                                    -3.Stream 操作是延迟执行的。这意味着,他们会等到需要结果的时候,才运行。


               3)Stream 操作有三个步骤:
                            a:创建 Stream:
                                    -1.根据 一个数据源(如:集合,数组),获取一个 对应的流。
                            b:中间操作:
                                    -1.一个中间操作链,对数据源的数据,进行处理。
                            c:终止操作(终端操作)
                                    -1.一旦执行 终止操作,才会执行 中间操作链 ,并产生结果,之后不会在被使用。


               4)Stream 创建对象操作(4种创建方式)
                            a:通过集合创建:

        //获取 集合
        List<Employee> employee = EmployeeData.getEmployee();

        //顺序流:按照 集合中 的顺序
        Stream<Employee> stream = employee.stream();
        //并行流:不按照集合的顺序,在集合中并行取数据
        Stream<Employee> employeeStream = employee.parallelStream();

                            b:通过数组创建 Stream

        //创建 数组
        String[] strings = {"张三", "李四", "王五"};
        
        Stream<String> stream = Arrays.stream(strings);

                            c:通过 Stream 的 of

        // 1
        Stream<Integer> integerStream = Stream.of(1, 2, 32, 32, 34);
        // 2
        Stream<String> fdsf = Stream.of("fdsf", "afdsf", "sadf");

                            d:创建无限流,可以造数据。
                                    -1.示例 1:

//        Stream.iterate(1, new UnaryOperator<Integer>() {
//            @Override
//            public Integer apply(Integer integer) {
//                return integer + 2;
//            }
//        });

        //使用 Lambda 创建,取 10 个数,
        Stream<Integer> iterate = Stream.iterate(1, integer -> integer + 2).limit(10);
        //终止操作。
        iterate.forEach(System.out::println);


               5)Stream 的中间操作(3):
                                多个中间操作,可以连接起来一个链,形成一个流水线。
                                除非流水线上触发终止操作,否则中间操作不会执行任何处理!
                                而在终止操作时,一次性全部处理,称为  “惰性求值”。

                            a:筛选与切片
                                    -1.过滤:filter(Predicate p)接收Lambda,从流中排除数据

        List<Employee> employee = EmployeeData.getEmployee();

        Stream<Employee> stream = employee.stream();

//        Stream<Employee> employeeStream = stream.filter(new Predicate<Employee>() {
//            @Override
//            public boolean test(Employee employee) {
//                return employee.getSalary() > 7000;
//            }
//        });

        Stream<Employee> employeeStream = stream.filter( employee1 -> employee1.getSalary() > 7000);

        employeeStream.forEach(System.out::print);

                                    -2.limit(int a):截断流:使其元素不会超过给定数量

        List<Employee> employee = EmployeeData.getEmployee();

        Stream<Employee> stream = employee.stream();

        Stream<Employee> employeeStream = stream.filter(employee1 -> employee1.getSalary() > 700);
        // 执行 截断
        Stream<Employee> limit = employeeStream.limit(2);

        limit.forEach(System.out::println);

                                    -3.skip(n):跳过元素:返回一个扔掉了,跳过前 n 个元素的流。若超过,则没结果。

        List<Employee> employee = EmployeeData.getEmployee();

        Stream<Employee> stream = employee.stream();

        Stream<Employee> employeeStream = stream.filter(employee1 -> employee1.getSalary() > 700);
        // 跳过 前两个 结果
        Stream<Employee> skip = employeeStream.skip(2);

        skip.forEach(System.out::println);

                                    -4.distinct():筛选:通过流 所生成 元素的 hashcode() 和 equals() 去除重复元素

        List<Employee> employee = EmployeeData.getEmployee();
        employee.add(new Employee(1003, "刘强东", 44, 234));
        employee.add(new Employee(1003, "刘强东", 44, 234));
        employee.add(new Employee(1003, "刘强东", 44, 234));

        Stream<Employee> stream = employee.stream();

        Stream<Employee> distinct = stream.distinct();

        distinct.forEach(System.out::println);



                            b:映射:
                                    -1.Map(Function f):接收一个函数,作为参数。将元素转换成 其他形式或提取信息,
                                                                     该函数,将会被应用到 每个元素上,并将其映射成一个新的元素。
                                                                     可以 将 list 里面的元素,挑选出来,转换为list<元素>的集合。

                                         1.例:将 list 里面字母,转换为大写

        List<String> strings = Arrays.asList("aa", "bb", "cc", "dd");

//        strings.stream().map(new Function<String, String>() {
//            @Override
//            public String apply(String s) {
//                return s.toUpperCase();
//            }
//        });

        strings.stream().map(s -> s.toUpperCase()).forEach(System.out::println);

                                         2.例:获取员工姓名长度 大于等于 3 的员工姓名 

        List<Employee> employee = EmployeeData.getEmployee();

        //使用 map()  映射出名字
        Stream<String> stringStream = employee.stream().map(Employee::getName);

        //过滤 名字长度 大于等于 3 的人
        Stream<String> stringStream1 = stringStream.filter(s -> s.length() >= 3);

        stringStream1.forEach(System.out::println);

                                         3.例:使用 方法引用:  

    public static void main(String[] args) {
        List<Person> list = GetList.getList();
        List<String> collect = list.stream()
                .map(Person::getUsername
                ).filter((s) -> {
                    return s.length() > 3;
                }).collect(Collectors.toList());

        System.out.println(collect);

    }



                                    -2.flatMap(Function f):
                                              
接收一个函数作为参数,将流中的每个值,都换成另一个流。
                                              然后把,所有流,连成一个流。(相当于 List 中 addAll() 方法 )
                                         1.

                                         2.

                                         3.



                            c:排序:
                                    -1.sorted():
                                              a.产生一个 新流,其中 按照自然顺序 排序。
                                              b.示例:

        List<Integer> integers = Arrays.asList(123, 23122, 3, 123);
        Stream<Integer> sorted = integers.stream().sorted();
        sorted.forEach(System.out::println);


                                    -2.sorted(Comparaotr com):
                                              a.产生一个新流,其中按比较器 顺序排序。
                                              b.示例:

        List<Employee> employee = EmployeeData.getEmployee();
        //根据年龄进行排序
        Stream<Employee> sorted = employee.stream().sorted((o1, o2) -> Integer.compare(o1.getAge(), o2.getAge()));

        sorted.forEach(System.out::println);

                                              c.如果排序相同,可以按照第二个字段(工资)排序:

        List<Employee> employee = EmployeeData.getEmployee();

        Stream<Employee> sorted = employee.stream().sorted(new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                int compare = Integer.compare(o1.getAge(), o2.getAge());
                if (compare != 0) {
                    return compare;
                } else {
                    return Double.compare(o1.getSalary(), o2.getSalary());
                }
            }
        });
        sorted.forEach(System.out::println);

 

 

               4)终止操作:
                            a:匹配与查找:
                                    -1.判断 是否都 

        //判断 流 里的对象的 年龄 是否都大于 18 岁
        List<Employee> employees = EmployeeData.getEmployee();
        Stream<Employee> stream = employees.stream();
//        boolean b = stream.allMatch(new Predicate<Employee>() {
//            @Override
//            public boolean test(Employee employee) {
//                return employee.getAge() > 18;
//            }
//        });
        boolean b1 = stream.allMatch(employee -> employee.getAge() > 18);
        System.out.println(b1);

                                    -2.检查是否至少匹配一个(查看是否存在)

        List<Employee> employees = EmployeeData.getEmployee();
        Stream<Employee> stream = employees.stream();

        //判断 是否存在 年龄 小于 33
        boolean b1 = stream.anyMatch(e -> e.getAge() < 33);

        System.out.println(b1);

                                    -3.检查是否 没有匹配元素(没有匹配元素 为 true,有则为 false)

        List<Employee> employees = EmployeeData.getEmployee();
        Stream<Employee> stream = employees.stream();

        //判断 是否存在 年龄 小于 33
        boolean b = stream.noneMatch(employee -> employee.getName().startsWith("马"));

        System.out.println(b);

                                    -4.返回第一个元素

        List<Employee> employees = EmployeeData.getEmployee();
        Stream<Employee> stream = employees.stream();

        Optional<Employee> first = stream.findFirst();

                                    -5.返回任意一个元素

        List<Employee> employees = EmployeeData.getEmployee();
        // 获取 并行流
        Stream<Employee> stream = employees.parallelStream();

        Optional<Employee> first = stream.findAny();

                                    -6.求流中 元素总个数

        List<Employee> employees = EmployeeData.getEmployee();
        Stream<Employee> stream = employees.parallelStream();
        // 统计 年龄 大于 40 的人 的个数
        long count = stream.filter(employee -> employee.getAge() > 40).count();

        System.out.println(count);

                                    -7.查找 流中  最大值、最小值

        List<Employee> employees = EmployeeData.getEmployee();
        Stream<Employee> stream = employees.parallelStream();
        // 查询 工资最高的人
        Optional<Employee> max = stream.max((o1, o2) -> Double.compare(o1.getSalary(), o2.getSalary()));

        System.out.println(max);

                                    -8.内部迭代(对于流的终止操作)(iterrater 指针,叫外部迭代)

        List<Employee> employees = EmployeeData.getEmployee();
        Stream<Employee> stream = employees.parallelStream();
        //终止操作  --内部迭代
        stream.forEach(System.out::println);


                            b:规约:
                                    -1.reduce():可以将 流中的元素 反复结合起来,得到一个值,返回。
                                             1.计算 1-10 自然数的和:

        //计算 1-10 自然数的和
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        //原始方式
//        Optional<Integer> reduce = Optional.ofNullable(list.stream().reduce(0, new BinaryOperator<Integer>() {
//            @Override
//            public Integer apply(Integer integer, Integer integer2) {
//                return Integer.sum(integer, integer2);
//            }
//        }));

         //lambda 表达式
//        Optional<Integer> reduce =
//                Optional.ofNullable(list.stream().reduce(0, (integer, integer2) -> Integer.sum(integer, integer2)));
        
        //
        Optional<Integer> reduce =
                Optional.ofNullable(list.stream().reduce(0, Integer::sum));

        System.out.println(reduce);

                                             2.求 所有员工 工资和:

        List<Employee> employee = EmployeeData.getEmployee();
        Optional<Double> reduce = employee.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println(reduce);

                                                或者:

        List<Employee> employee = EmployeeData.getEmployee();
        Optional<Double> reduce = employee.stream().map(Employee::getSalary).reduce((d1, d2) -> d1 + d2);
        System.out.println(reduce);



                            c:收集
                                    -1.collect(Collector c):收集
                                             将 流 转换为 其他形式,收集 一个 Collector 接口的实现,用于给 Stream 中 元素做汇总的方法。
                                            Collector 接口中,方法的实现 决定了如何对流执行收集的操作(如:收集到 List,Set,Map)。
                                            另外,Collectors 类,提供了很多静态方法,可以方便的创建,常见收集器实例。
 
                                    -2.将 过滤后的流,转换为 List 集合:

        List<Employee> employee = EmployeeData.getEmployee();
        List<Employee> collect = employee.stream().collect(Collectors.toList());
        
//        for (Employee e : collect) {
//            System.out.println(e.toString());
//        }

        collect.forEach(System.out::println);








 

六:Optional 类(最大化减少空指针异常)


               1)Optional 类介绍:

                            a:Optional :是一个容器类,可以避免 空指针异常。
                                   他可以保存 类型 T 的值,代表这个值存在。这是一个 可以为 Null 的容器对象
                                   如果 值存在 ,调用    方法 会返回 true,调用 get()  方法 ,返回该对象 。

               2)常用方法: 

                                    -1.Optional.of(T  t) : 创建一个 Optional 实例,t 必须为 非空(不能为空)。

        Stu stu = new Stu();

        //stu = null;

        Optional<Stu> stu1 = Optional.of(stu);

        System.out.println(stu1);

                                    -2.Optional.ofNullable( T  t ) : 创建一个 Optional 实例,t 可以为空。

        Stu stu = new Stu();

        //stu = null;

        Optional<Stu> stu1 = Optional.ofNullable(stu);

        System.out.println(stu1);

                                    -3.orElse(T  t):

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值