• Java8 新特性1—— Lambda表达式、内置函数式接口、方法引用与构造器引用


    lambda 表达式

    Lambda 允许把函数作为一个方法的参数(函数作为参数传递到方法中)

    基本语法(parameters) -> expression(parameters) ->{ statements; },由 参数域,"->",实现方法 三部分组成。

    注意事项

    1. 当参数为空时,参数域由 ()表示即可,多个参数时,参数之间用逗号","分隔;
    2. 参数不要求指定变量类型,编译器会根据代码上下文推断自动鉴别;
    3. 当实现方法只有一条语句时,{}可省略,当方法无返回值时,return 关键字可省略;

    使用条件
    lambda 表达式主要用来实现行内执行的函数式接口;
    函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,并且接口需要用_@FunctionalInterface_ 注解修饰,例如:

    @FunctionalInterface
    interface GreetingService 
    {
        void sayMessage(String message);
    }
    

    在Java8之前,一般用匿名内部类的方式来实现接口内的抽象方法,Java8可以使用lambda表达式来实现,以精简代码;


    核心函数式接口

    由于lambda表达式是来实现函数式接口的,所以使用之前需要先定义对应的函数式接口,大量使用会导致代码文件琐碎繁复,因此Java8针对常见的使用的场景,已经内置了大部分函数式接口,只有少部分需要我们自己单独定义;

    Java内置了四大核心函数式接口

    函数式接口 类型参数 返回类型 用途
    Consumer
    消费型接口
    T void 对类型为T的对象应用操作,
    包含方法:void accept(T t);
    Supplier
    供给型接口
    T 返回类型为T的对象,
    包含方法:T get();
    Funtional<T,R>
    函数型接口
    T R 对类型为T的对象应用操作,并返回结果是R类型的对象,
    包含方法:R apply(T,t);
    Predicate
    断言型接口
    T boolean 确定类型为T的对象是否满足某种约束,并返回boolean值,
    包含方法:boolean test(T,t);

    其他接口

    函数式接口 参数类型 返回类型 用途
    BiFunction<T, U, R> T, U R 对类型为 T, U 参数应用操作,返回 R 类型的结果。
    包含方法为R apply(T t, U u);
    UnaryOperator
    (Function子接口)
    T T 对类型为T的对象进行一元运算,并返回T类型的结果。
    包含方法为T apply(T t);
    BinaryOperator
    (BiFunction 子接口)
    T, T T 对类型为T的对象进行二元运算,并返回T类型的结果。
    包含方法为: T apply(T t1, T t2);
    BiConsumer<T, U> T, U void 对 类 型 为 T, U 参数 应 用操作。
    包含方法为void accept(T t, U u)
    ToIntFunction
    ToLongFunction
    ToDoubleFunction
    T int
    long
    double
    分 别 计 算 int 、 long 、double、值的函数
    IntFunction
    LongFunction
    DoubleFunction
    int
    long
    double
    R 参 数 分 别 为 int 、 long 、double 类型的函数

    结合lambda表达式和内置函数式接口的代码示例

    public void checkSalary(List<Employee> employees, Predicate<Employee> p){
        for(Employee employee:employees){
          if (p.test(employee)) {
            System.out.println(employee.getName());
          }
        }
      }
      @Test
      public void testLambda(){
        List<Employee> employeeList = Arrays.asList(
                new Employee("张三",2500,34),
                new Employee("李四",4500,45),
                new Employee("lisi",3500,35),
                new Employee("zhangsan",3000,30));
        // 筛选出所有薪水在3000元以上的员工姓名
        checkSalary(employeeList,(e)->e.getSalary()>3000);
      }
    

    方法引用与构造器引用

    方法引用

    当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!(实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!)方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来。
    如下三种主要使用情况 :

    • 对象::实例方法
    • 类::静态方法
    • 类::实例方法
    //例如
    (x) -> System.out.println(x);
    //等同于
    System.out::println
    //例如
    BinaryOperator<Double> bo = (x,y) -> Math.pow(x,y);
    //等同于
    BinaryOperator<Double> bo = Math::pow;
    //例如
    compare((x,y) -> x.equals(y), "abcdef","abcdef");
    //等同于
    compare(String::equals,"abc","abc");
    

    注意:当需要引用方法的第一个参数是调用对象,并且第二个参数是需要引用方法的第二个参数(或无参数)时:ClassName::methodName

    构造器引用

    格式:ClassName::new

    与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中抽象方法的参数列表一致

    数组引用

    格式: type[] :: new

    // 例如:
    Function<Integer,Integer[]> fun = (n) -> new Integer[n];
    // 等同于:
    Function<Integer,Integer[]> fun = Integer[]::new;
    


  • 相关阅读:
    jdk7_ConcurrentHashMap 图示
    Teradata 日期函数
    Teradata正则表达式
    Teradata sql去除字段中的字母/数字
    sql查询连续3天有交易记录的客户
    批量生成sql查询语句
    sql查询字段中是否含有字母/数字/符号
    sql查询每个人最新的2个电话号码
    python连接Teradata数据库
    dos命令获取文件行数
  • 原文地址:https://www.cnblogs.com/geekHao/p/12441460.html
Copyright © 2020-2023  润新知