Lambda表达式快速回顾

1.概述

Lambda表达式是Java8中的新特性,编码时,我们一般尽可能轻量级的将代码封装为数据,传统的解决方案是通过接口和实现类(匿名内部类)实现,这中方式存在语法冗余,this关键字,变量捕捉,数据控制等问题.

例如线程的创建方式:(传统的:)

new Thread(new Runnable() {

            @Override

            public void run() {

                System.out.println(Thread.currentThread().getId());

            }

        }).start();

使用lambda表达式语法:

new Thread(()->{

            System.out.println(Thread.currentThread().getId());

        }).start();

二.基础语法

  1. Lambda表达式在Java语言中引入了一个操作符**“->”**,该操作符被称为Lambda操作符或箭头操作符。它将Lambda分为两个部分:
  • 左侧:指定了Lambda表达式需要的所有参数
  • 右侧:制定了Lambda体,即Lambda表达式要执行的功能。

组成Lambda表达式的三要素:形式参数,箭头,代码块

Lambda表达式的格式

、格式:(形式参数) -> {代码块}

、形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可

->:由英文中画线和大于符号组成,固定写法。代表指向动作

、代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

  1. 语法格式的特征:

①无参,无返回值,Lambda体只需一条语句

public void test01(){

            Runnable runnable=()-> System.out.println("Runnable 运行");

            runnable.run();//结果:Runnable 运行

          }

②Lambda需要一个参数,无返回值

public void test02(){

    Consumer<String> consumer=(x)-> System.out.println(x);

    consumer.accept("Hello Consumer");//结果:Hello Consumer

  }

 ③Lambda只需要一个参数时,参数的小括号可以省略

  public void test02(){

    Consumer<String> consumer=x-> System.out.println(x);

    consumer.accept("Hello Consumer");//结果:Hello Consumer

  }

④Lambda需要两个参数,并且Lambda体中有多条语句。

 

  public void test04(){

    Comparator<Integer> com=(x, y)->{

      System.out.println("函数式接口");

      return Integer.compare(x,y);

    };

    System.out.println(com.compare(2,4));//结果:-1

  }

⑤有两个以上参数,有返回值,若Lambda体中只有一条语句,return和大括号都可以省略不写

  public void test05(){

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

    System.out.println(com.compare(4,2));//结果:1

  }

⑥Lambda表达式的参数列表的数据类型可以省略不写,因为JVM可以通过上下文推断出数据类型,即“类型推断”

   public void test06(){

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

    System.out.println(com.compare(4,2));//结果:1

  }

(类型推断:在执行javac编译程序时,JVM根据程序的上下文推断出了参数的类型。Lambda表达式依赖于上下文环境。)

三.函数式接口

1.定义:只包含一个抽象方法的接口,就称为函数式接口。

我们可以通过Lambda表达式来创建该接口的实现对象。

我们可以在任意函数式接口上使用@FunctionalInterface注解,这样做可以用于检测它是否是一个函数式接口,同时javadoc也会包含一条声明,说明这个接口是一个函数式接口。

2.自定义函数式接口

public class FunctionInterface{

    //按照函数式接口的定义,自定义一个函数式接口

    @FunctionalInterface

    public interface MyFunction<T>{

        public T getValue(String str);

    }

    //定义一个方法将函数式接口作为方法参数

    public String toLowerString(MyFunction<String> str,String origin){

        return str.getValue(origin);

    }

    //Lambda表达式实现的接口作为参数传递。

    @Test

    public void test(){

        String value = toLowerString((str)->{

            return str.toString();

        },"ABC");

        System.out.println(value);  //ABC

    }

}

四.lambda表达式的作用域

Lambda表达式可以看作是匿名内部类实例化的对象,Lambda表达式对变量的访问限制和匿名内部类一样,因此Lambda表达式可以访问局部变量、局部引用,静态变量,实例变量。

1.访问局部变量

public class TestFinalVariable {

    interface VarTestInterface{

        Integer change(String str);

    }

    public static void main(String[] args) {

       //局部变量不使用final修饰

        Integer tempInt = 1;

        VarTestInterface var = (str -> Integer.valueOf(str+tempInt));

        //再次修改,不符合隐式final定义

        tempInt =2;

        Integer str =var.change("111") ;

        System.out.println(str);

    }

}

上面的代码会报错(Error:(12, 60) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量),即final

特殊情况下,局部变量也可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

例如上面的代码确保Lambda表达式后局部变量后面不做修改,就可以成功啦!

2.访问局部引用,静态变量,实例变量

Lambda表达式不限制访问局部引用变量,静态变量,实例变量。代码测试都可正常执行,代码:

public class LambdaScopeTest {

    /**

     * 静态变量

     */

    private static String staticVar;

    /**

     * 实例变量

     */

    private static String instanceVar;

    @FunctionalInterface

    interface VarChangeInterface{

        Integer change(String str);

    }

    /**

     * 测试引用变量

     */

    private void  testReferenceVar(){

        ArrayList<String> list = new ArrayList<>();

        list.add("111");

        //访问外部引用局部引用变量

        VarChangeInterface varChangeInterface = ((str) -> Integer.valueOf(list.get(0)));

        //修改局部引用变量

        list.set(0,"222");

        Integer str =varChangeInterface.change("");

        System.out.println(str);

    }

    /**

     * 测试静态变量

     */

    void testStaticVar(){

        staticVar="222";

        VarChangeInterface varChangeInterface = (str -> Integer.valueOf(str+staticVar));

        staticVar="333";

        Integer str =varChangeInterface.change("111") ;

        System.out.println(str);

    }

    /**

     * 测试实例变量

     */

    void testInstanceVar(){

        instanceVar="222";

        VarChangeInterface varChangeInterface = (str -> Integer.valueOf(str+instanceVar));

        instanceVar="333";

        Integer str =varChangeInterface.change("111") ;

        System.out.println(str);

    }

    public static void main(String[] args) {

        new LambdaScopeTest().testReferenceVar();

        new LambdaScopeTest().testStaticVar();

        new LambdaScopeTest().testInstanceVar();

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟a小李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值