zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    HDU 4348 To the moon(可持久化线段树)
    HDU 5875 Function 大连网络赛 线段树
    HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
    HDU 5876 大连网络赛 Sparse Graph
    HDU 5701 中位数计数 百度之星初赛
    CodeForces 708B Recover the String
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    ASP.NET生成验证码
    ASP.NET生成验证码
    ASP.NET生成验证码
  • 原文地址:https://www.cnblogs.com/AganRun/p/11816069.html
Copyright © 2011-2022 走看看