首页 > 编程语言 >Java SE 宋红康 days04-高级篇-Java8新特性

Java SE 宋红康 days04-高级篇-Java8新特性

时间:2022-10-04 21:01:22浏览次数:52  
标签:Java Stream System Employee days04 println Lambda 宋红康 out

Java8两大最重要的改变:Lambda表达式和Stream API

集合讲的是数据,Stream讲的是计算

1. Lambda 表达式

  Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)

2. Lambda 表达式的介绍

  -> :lambda操作符、箭头操作符

  左边:lambda 形参列表(其实就是接口中的抽象方法的形参列表)

  右边:lambda 体(其实就是重写的抽象方法的方法体)

3. Lambda 表达式的使用

  分为 6 种语法介绍

  格式一:无参、无返回值。Runnable  r1  =  () -> { System.out.println(" ..... ") ;};

  格式二:Lambda 需要一个参数,但是没有返回值。Consumer<String>  con  =  (String str) -> { System.out.println(str) ;};

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

      Consumer<String>  con  =  (str) -> { System.out.println(str) ;};

  格式四:Lambda 若只需要一个参数时, 参数的小括号可以省略。Consumer<String>  con  =  str -> { System.out.println(str) ;};

  格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值。

      1.  Conparator<Integer>  com  =  (x,y) -> {
      2.  System.out.printLn("实现函数式接口方法!");
      3.    return Integer.compare(x,y);
      4.  }

  格式六:当 Lambda 体只有一条语句时,return与大括号都可以省。

      Conparator<Integer>  com  =  (x,y) -> Integer.compare(x,y);

4. Lambda的本质是作为函数式接口的实例;

5. 总结

  左边:lambda 形参列表的参数类型可以省略(类型推断);如果 lambda 形参列表只有一个参数,其一对()也可以省略;

  右边:lambda 体应该使用一对 { } 包裹;如果 lambda 体只有一条执行语句(可能是return语句),可以省略这一对 { } 和 return 关键字;

6. 函数式接口:如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口;

  •   可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明)。
  •   可以在接口上使用 @FunctionalInterface 注解,检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
  •   在java.util.function包下定义了Java 8 的丰富的函数式接口

7. 内置四大核心函数式接口

  

 8. 方法引用

    ① 使用情景:当要传递给 lambda 体的操作,已经有实现的方法了,可以使用方法引用。

    ② 方法引用本质上还是 lambda 表达式,而 lambda 表达式作为函数式接口的实例,所以方法引用也是函数式接口的实例;

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

    ④ 使用格式:类(或对象)::方法名

      具体可以分为3种情况:

      情况一:对象::非静态方法

     // 情况一 对象::实例方法(非静态方法,所以需要类去调用)

        // Consumer中的 void accept(T t)
        // PrintStream中的 void println(T t)
        Consumer<String> con1 = str -> System.out.println(str);
        con1.accept("beijing");
        System.out.println("*************************");
        Consumer<String> con2 = System.out::println;
        con2.accept("北京");

        // Employee中的 String getName()
        // Supplier中的 T get()
        Employee emp = new Employee("jack", 5000, 2012, 10, 20);
        Supplier<String> sup1 = () -> emp.getName();
        System.out.println(sup1.get());
        System.out.println("*************************");
        Supplier<String> sup2 = emp::getName;
        System.out.println(sup2.get());

      情况二:类::静态方法

        // 情况二 类::静态方法

        // Comparator中的 int compare(T t1, T t2)
        // Integer中的 int compare(T t1, T t2)
        Comparator<Integer> com1 = (t1, t2) -> Integer.compare(t1, t2);
        System.out.println(com1.compare(12,24));
        System.out.println("*************************");
        Comparator<Integer> com2 = Integer::compare;
        System.out.println(com2.compare(12,24));

        // Function中的 R apply(T t)
        // Math中的 Long round(Double d)
        Function<Double, Long> func = new Function<Double, Long>() {
            @Override
            public Long apply(Double d) {
                return Math.round(d);
            }
        };
        Function<Double, Long> func1 = d -> Math.round(d);
        System.out.println(func1.apply(24.0));
        System.out.println("*************************");
        Function<Double, Long> func2 = Math::round;
        System.out.println(func1.apply(24.0));

      情况三:类::非静态方法

        // 情况三 类::实例方法

        // Comparator中的 int compare(T t1, T t2)
        // String中的 int t1.compareTo(t2)
        Comparator<String> com1 = (s1, s2) -> s1.compareTo(s2);
        System.out.println(com1.compare("abc", "bcd"));
        System.out.println("*************************");
        Comparator<String> com2 = String::compareTo;
        System.out.println(com2.compare("abc", "bcd"));

        // BiPredicate中的 boolean test(T t1, T t2)
        // String中的 boolean t1.equals(t2)
        BiPredicate<String, String> pre1 = (s1, s2) -> s1.equals(s2);
        BiPredicate<String, String> pre2 = String::equals;

        // Function中的 R apply(T t)
        // Employee中的 String getName()
        Employee employee = new Employee("jack", 5000, 2012, 10, 20);
        Function<Employee, String> func1 = e -> e.getName();
        System.out.println(func1.apply(employee));
        System.out.println("*************************");
        Function<Employee, String> func2 = Employee::getName;
        System.out.println(func2.apply(employee));

9. 构造器引用和数组引用

  构造器引用

    和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致;

    抽象方法的返回值类型即为构造器所属的类的类型;

  数组引用:可以把数组看作一个特殊的类,写法与构造器引用一致;

        // 构造器引用

        // Supplier中的 T get()
        // Employee的无参构造器:Employee()
        Supplier<Employee> sup = new Supplier<Employee>() {
            @Override
            public Employee get() {
                return new Employee();
            }
        };
        Supplier<Employee> sup1 = () -> new Employee();
        System.out.println("*************************");
        Supplier<Employee> sup2 = Employee::new;

        // Function中的 R apply(T t)
        Function<Integer, Employee> func1 = id -> new Employee(id);
        Employee employee = func1.apply(1001);
        System.out.println("*************************");
        Function<Integer, Employee> func1 = Employee::new;

        // Function中的 R apply(T t, U u)
        Function<Integer, String, Employee> func2 = (id,name) -> new Employee(id, name);
        Employee employee1 = func1.apply(1001, "ACX");
        System.out.println("*************************");
        Function<Integer, String, Employee> func3 = Employee::new;

10. Stream API

  ① Stream关注的是对数据的运算,与CPU打交道;集合关注的是数据的存储,与内存打交道;

  ② 注意点:

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

  ③ Stream 执行流程

    stream实例化 ---->  一系列的中间操作(过滤、映射、...) ---->  终止操作

  ④ 说明

    1. 一个中间操作链,对数据源的数据进行处理
    2. 一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用

11. Stream 实例化

  创建

    方式一:通过集合

      • default Stream<E> stream() : 返回一个顺序流(拿数据的时候按顺序取)
      • default Stream<E> parallelStream() : 返回一个并行流(类似多线程随机取)

    方式二:通过数组(Java8 中的 Arrays 的静态方法 stream() 可以获取数组流)

      • static <T> Stream<T> stream(T[] array): 返回一个流

    方式三:通过Stream 的of()

      • public static<T> Stream<T> of(T... values) : 返回一个流

    方式四:创建无限流

      • 迭代  public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
      • 生成  public static<T> Stream<T> generate(Supplier<T> s)

  中间操作

    筛选与切片

      

        List<Employee> empList = EmployeeData.getEmployees();
        // filter(Predicate p)——接收 Lambda , 从流中排除某些元素
        Stream<Employee> stream = empList.stream();
            // 练习1 查询员工表中薪资大于7000的员工信息
            stream.filter(e->e.getSalary() > 7000).forEach(System.out::println);
        // limit(n)——截断流,使其元素不超过给定数量
        empList.stream().limit(3).forEach(System.out::println);
        // skip(n)——跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
        empList.stream().skip(3).forEach(System.out::println);
        // distinct()——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
        empList.stream().distinct().forEach(System.out::println);

    映射

      

    排序

      

  终止操作

    匹配与查找

      

 

 

       

    归约

      

    收集

       

 

12. Optional类:解决空指针问题;

标签:Java,Stream,System,Employee,days04,println,Lambda,宋红康,out
From: https://www.cnblogs.com/LinxhzZ/p/16754391.html

相关文章

  • 01.JavaScript简介
    JavaScript(JS)isalightweight,interpreted,orjust-in-timecompiledprogramminglanguagewithfirst-classfunctions.Whileitismostwell-knownasthe......
  • java---抽象类
    抽象类1.abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法,如果修饰类,那么该类就是抽象类2.抽象类中可以没有抽象方法,但是有抽象方法的类,......
  • java算法——自建对数器
    用于验证所写算法是否正确,与java自带的函数方法进行比较,例如写一个排序算法,验证排序算法是否正确,采用Arrays.sort(arr)的方式,与自己所写的算法进行比对,经过多轮(比较大的一......
  • JavaWeb--数据库连接池,SpringJDBC
    JavaWeb--数据库连接池,SpringJDBCJavaWeb--数据库连接池概述其实就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,......
  • java 算法——异或运算练习
    packageclass01;//在一个数组中已知数组中只有一种数出现了奇数次,其他的是所有数都出现了偶数次怎么找到出现奇数次的数对所有数字取异或最终结果就是奇数次那个数......
  • java算法——二分法及其拓展
    题目描述:在一个无序数组中,任何相邻的两个数一定不相等,求规定范围内它局部最小的那个数要求:计算的过程时间复杂度小于O(N)思路:由于所有相邻的两个数一定不相等,若一个数的左......
  • Java PriorityQueue(优先队列)实现大顶堆和小顶堆
    JavaPriorityQueue类是一种队列数据结构实现它与遵循FIFO(先进先出)算法的标准队列不同。//默认为小顶堆PriorityQueue<Integer>minHeap=newPriorityQueue<>(k,(a,b......
  • JAVA学习网站
    1、菜鸟教程Java教程|菜鸟教程(runoob.com)  2、Maven依赖MavenRepository:Search/Browse/Explore(mvnrepository.com)  3、Leecode算题神站力扣(LeetCo......
  • java的jvm堆中的内存泄露和内存溢出的概念以及区别【杭州多测师】【杭州多测师_王sir
    一、什么是内存溢出和内存泄露内存泄漏(memoryleak):是指程序在申请内存后,无法释放已申请的内存空间,导致系统无法及时回收内存并且分配给其他进程使用。通常少次数的内存无......
  • 【Java8新特性】- 接口中默认方法修饰为普通方法
    Java8新特性-接口中默认方法修饰为普通方法......