Lambda表达式与函数式接口

Lambda表达式

  1. 为什么需要引入Lambda表达式?

    答:为了方便代码块的传递,Lambda表达式是一个可传递的代码块,因为java是面向对象的编程,所以不能直接在将代码块进行传递,需要将所需要的代码块放在一个对象里面,所以这个对象对应的类必须有一个方法包含所需要传递的代码。其他语言可以直接处理代码块不需要用对象;

    带参数变量的表达式就被称为Lambda表达式。

  2. 语法

  • 第一个Lambda表达式

    (String fiirst,String sencond)->first.length-second.length;
    //参数 —>表达式
    

    注意:需要严格规定变量的类型,由于java是一种强类型的语言

    • 即使没有变量也要写()->表达式

    • 如果可以推导出参数的类型可以省略参数的类型

      Comparator<String> comp = (first,second)->{};
      //此时可以推出是String类型
      
    • 如果只有一个参数且可以推断出该参数的类型,即使是()也可以省略;

    • 无需指定Lambda表达式的返回值类型,它会根据上下文推导得到;

  • 第二个表达式:如果后面的表达式一个式子写不完就写成{}方法体的形式

    (String first,String second)->
    	{
         //执行的代码 
    	}
    
  1. 函数式接口

    比如Comparator

    lambda表达式与这些接口是兼容的

    @FunctionalInterface注解标注函数式接口

    functional interface:只有一个抽象方法的接口,需要这种接口的对象的时候,可以通过Lambda表达式来实现;【接口可以有非抽象的方法】

    也就是说Lambda表达式就是函数式接口中抽象方法覆写的方法体内容;

    函数式接口其实就是指只含有一个抽象方法的接口,其目的就是用来传递代码块也就是Lambda表达式

    为有特定用途的Lambda表达式建立特定的函数式接口作为传递表达式

    Arrays.sort(word,(first,second)->first.length-second.length)
    //1.Arrays.sort()底层会接收实现了Comparator<String>的某个类的对象。在对象上调用compare方法执行lambda表达式的方法体
    
  • lambda表达式可以转换为接口【函数式接口才可以使用lambda表达式】java.util.functon中有很多函数式接口
  1. 保存Lambda表达式变量

    Comparator<String> comp = (first,second)->first.length-second.length;
    //相当于实现了Comparator类型的实例对象,并且该对象还覆写了抽象方法并且方法体为Lambda表达式对应的内容
    
  2. 方法引用

    Timer timer = new Timer(1000,System.out::println);
    //实现将System.out中的方法引用到ActionListener函数式接口实现对象的覆写方法中;
    

    实现步骤:

    • 指示编译器生成一个函数式接口的实例
    • 覆写函数式接口中的抽象方法
    • 在方法中引用System.out的println方法作为方法体实现方法引用

    语法

    对象或类名称::方法名称 //实现方法传递等价于(参数类型 参数名称)->类.方法()
    

    注意:

    • 只有当Lambda表达式的体只有一个方法不做其他操作的情况下才能把Lambda表达式重写为方法引用;

    • 方法引用中可以使用this参数以及super

      this::equals 
      //等价于下面
      x->this.equals(x)
      
  3. 构造器引用

    Person::new 
    //等同于以下,参数根据上下文决定重载哪个构造器 
    ()->new Person()
    
  4. 变量作用域

    希望能够使得Lambda表达式访问外围变量也就是非Lambda代码块中的变量

    Lambda表达式包括三个部分:

    • 一个代码块
    • 参数
    • 自由变量值,指的非参数且不在代码中定义的变量

    Lambda表达式的作用域与嵌套它的代码块作用域相同;

    public static void repeatMessage(String text,int delay){
        ActionListener listener = event->
        {
            System.out.println(text);
        }
        new Timer (delay,listener).start;
    }
    

    lambda表达式会存储自由变量的值,也可以说自由变量被Lambda表达式捕获了。关于代码块和自由变量有一个术语:闭包在java中Lambda表达式就是闭包(closure).

    上述例子中text变量就是自由变量,

    注意:

    • 在Lambda中只能引用的外部作用域变量不能改变变量
    • 被Lambda表达式引用的变量在外部也是不可改变的。
    • Lambda表达式中捕获的变量必须实际上是事实最终变量(这个变量初始化后就不会再为其赋新值。)
  5. 在Lambda表达式中使用this关键字

    public class Application{
        public void test(){
            ActionListener listener = event->
            {
                System.out.println(this.toString());
            }
        }
    }
    

    上述的this指代的是创建这个Lambda表达式的方法的this参数;所以上述的this指的就是Application对应的实例对象中的方法而不是ActionListener。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值