• Java8特性Lambda表达式


    Lambda 表达式

    简介:

    • Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
    • Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
    (parameters) -> expression
     或
     (parameters) ->{ statements; }
    

    使用 Lambda 表达式需要注意以下两点:

    • Lambda 表达式主要用来定义行内执行的方法类型接口,例如,一个简单方法接口。在上面例子中,我们使用各种类型的Lambda表达式来定义MathOperation接口的方法。然后我们定义了sayMessage的执行。
    • Lambda 表达式免去了使用匿名方法的麻烦,并且给予Java简单但是强大的函数化的编程能力。

    变量作用域

    lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误 。

    我们也可以直接在 lambda 表达式中访问外层的局部变量。

    final int num = 1;
    Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2);  // 输出结果为 3 
    

    lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

    在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

    方法引用

    • 方法引用通过方法的名字来指向一个方法。
    • 方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
    • 方法引用使用一对冒号 :: 。

    函数式接口

    函数式接口

    有且只有一个抽象方法的接口,称之为函数式接口。当然接口中可以有其他方法(默认,静态,私有)

    @FunctionInterface注解:可以检测接口是否是函数式接口
    是:编译成功, 否:编译失败

    函数式接口的使用:

    一般可以作为方法的参数和返回值类型

    例子:
    1.定义一个函数式接口MyFunctionInterface中定义一个没有返回值的方法public void method();
    2.定义一个接口的实现类MyFunctionInterFaceImpl实现函数式接口
    3.定义一个测试类Demo中有一个静态方法show参数是这个函数式接口,调用接口中的方法public static void show(MyFunctionInterface myface){myface.method();}
    4.在main方法中调用show方法的3中方式
    a.调用show方法,参数是接口,所以可以传接口的实现类
    show(new MyFunctionInterfaceImpl());
    b.方法参数是一个接口,所以可以传递接口的匿名内部类
    show(new MyFunctionInterface(){
    @override
    public void method(){System.out.print(“使用匿名内部类重写接口中的抽象方法”);}
    });
    c.调用show方法,方法参数是一个函数式接口所以可以使用Lambda表达式
    show(()->{System.out.print(“使用lambda重写接口中的抽象方法”)});

    函数式编程

    1. 函数式编程:使用Lambda表达式和方法引用简化程序。
    2. Lambda表达式的延迟执行:有些场景的代码执行后,结果不一定会被使用,从而造成性能的浪费。而Lambda是延迟执行的,这正好可以作为解决方法,提升性能。
    3. 函数式接口作为方法的参数和返回值。
      存在函数式接口就可以使用Lambda表达式。即可以使用Lambda进行传参。

    使用Lambda优化日志案例:

    1.Lambda的特点:延迟加载 lambda使用的前提:必须存在函数式接口(定义拼接字符串的接口)  
    2.使用Lambda表达式作为参数传递,仅仅是把参数传递showLogger方法中,只有满足条件,日志的等级是1级才会调用接口MessageBuilder中的方法builderMessage才会进行拼接字符串。  
    

    常用的函数式接口(java.util.function包中)

    Supplier接口

    Java.util.function.Supplier<T> 接口中仅包含一个无参的方法:T get()。  
    用来获取一个泛型参数指定类型的接口数据。  
    由于是一个函数式接口,这就意味着对应的Lambda表达式对外提供一个符合泛型类型的对象数据.  
    Supplier<T>接口被称为生产型接口,指定接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据
    

    Consumer接口

    Java.util.function.Consumer<T>接口正好与Supplier接口相反,他不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。  
    Consumer中包含抽象方法void accept(T t),意为消费一个指定泛型的数据。
    Consumer接口是一个消费型接口,泛型执行什么类型,就可以使用accept方法消费什么类型的数据
    

    .foreach(Consumer t)

    Consumer中的默认方法andThen:组合消费   练习题
    如果一个方法的参数和返回值全是Consumer类型,那么就可以实现效果:  
    消费的时候,首先做一个操作,然后再做一个操作,实现组合。要想实现组合,就需要两个个Lambda表达式。
    

    Predicate接口 判断

    Java.util.function.Predicate: 
    Predicate接口对某种数据类型进行判断,从而得到一个boolean值结果。
    Predicate接口中的抽象方法:boolean Test(T t)用来对指定类型的数据进行判断方法
    结果:符合条件:返回true
          不符合条件:返回flase
    默认方法:and or ! 练习题
    

    .filter(Predicate t)

    Function接口

    Java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。  
    抽象方法:R apply(T t) 根据T的类型参数获取R类型的结果
    

    .map(Function<Object, Object> f)

  • 相关阅读:
    javaweb学习2
    javaweb学习1
    Java学习17
    python 正则表达式
    python 常用库
    python 常用内置函数
    python 函数高级功能
    python 正则表达式findall
    tcpdump
    安卓软件学习进度_1
  • 原文地址:https://www.cnblogs.com/AganRun/p/11816069.html
Copyright © 2020-2023  润新知