Lambda 表达式

Lambda 表达式是在 Java 8 中引入的,并且成为了 Java 8 最大的特点。它使得功能性编程变得非常便利,极大地简化了开发工作。

语法
一个 Lambda 表达式具有下面这样的语法特征。它由三个部分组成:第一部分为一个括号内用逗号分隔的参数列表,参数即函数式接口里面方法的参数;第二部分为一个箭头符号:->;第三部分为方法体,可以是表达式和代码块。语法如下:

parameter -> expression body

下面列举了 Lambda 表达式的几个最重要的特征:

  • 可选的类型声明:你不用去声明参数的类型。编译器可以从参数的值来推断它是什么类型。
  • 可选的参数周围的括号:你可以不用在括号内声明单个参数。但是对于很多参数的情况,括号是必需的。
    可选的大括号:如果表达式体里面只有一个语句,那么你不必用大括号括起来。
  • 可选的返回关键字:如果表达式体只有单个表达式用于值的返回,那么编译器会自动完成这一步。若要指示表达式来返回某个值,则需要使用大括号。
    语言的设计者们思考了很多如何让现有的功能和 Lambda 表达式友好兼容。于是就有了函数接口这个概念。函数接口是一种只有一个方法的接口,函数接口可以隐式地转换成 Lambda 表达式。

函数式接口的重要属性是:我们能够使用 Lambda 实例化它们,Lambda 表达式让你能够将函数作为方法参数,或者将代码作为数据对待。Lambda 表达式的引入给开发者带来了不少优点:在 Java 8 之前,匿名内部类,监听器和事件处理器的使用都显得很冗长,代码可读性很差,Lambda 表达式的应用则使代码变得更加紧凑,可读性增强;Lambda 表达式使并行操作大集合变得很方便,可以充分发挥多核 CPU 的优势,更易于为多核处理器编写代码。引用自 IBM - Java 8 新特性概述。

例如

public class Tester{
    public static void main(String args[]){
        Tester tester = new Tester();

        // 带有类型声明的表达式
        MathOperation addition = (int a, int b) -> a + b;

        // 没有类型声明的表达式
        MathOperation subtraction = (a, b) -> a - b;

        // 带有大括号、带有返回语句的表达式
        MathOperation multiplication = (int a, int b) -> { return a * b; };

        // 没有大括号和 return 语句的表达式
        MathOperation division = (int a, int b) -> a / b;

        // 输出结果
        System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
        System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
        System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
        System.out.println("10 / 5 = " + tester.operate(10, 5, division));

        // 没有括号的表达式
        GreetingService greetService1 = message ->
        System.out.println("Hello " + message);

        // 有括号的表达式
         GreetingService greetService2 = (message) ->
        System.out.println("Hello " + message);

        // 调用 sayMessage 方法输出结果
        greetService1.sayMessage("Shiyanlou");
        greetService2.sayMessage("Classmate");
    }

    // 下面是定义的一些接口和方法

    interface MathOperation{
        int operation(int a, int b);
    }

    interface GreetingService{
        void sayMessage(String message);
    }

    private int operate(int a, int b, MathOperation mathOperation){
        return mathOperation.operation(a, b);
    }
}

需要注意的是:

  • Lambda 表达式优先用于定义功能接口在行内的实现,即单个方法只有一个接口。在上面的例子中,我们用了多个类型的 Lambda 表达式来定义 MathOperation 接口的操作方法。然后我们定义了 GreetingService 的 sayMessage 的实现。
  • Lambda 表达式让匿名类不再需要,这为 Java 增添了简洁但实用的函数式编程能力。

作用域
我们可以通过下面这段代码来学习 Lambda 的作用域。请将代码修改至如下这些:

public class NewFeaturesTester{
    final static String salutation = "Hello "; // 正确,不可再次赋值
    // static String salutation = "Hello "; // 正确,可再次赋值
    // String salutation = "Hello "; // 报错
    // final String salutation = "Hello "; // 报错

    public static void main(String args[]){
        // final String salutation = "Hello "; // 正确,不可再次赋值
        // String salutation = "Hello "; // 正确,隐性为 final,不可再次赋值

        // salution = "welcome to "
        GreetingService greetService1 = message ->
        System.out.println(salutation + message);
        greetService1.sayMessage("Lambda");
    }

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

可以得到以下结论:

  • 可访问 static 修饰的成员变量,如果是 final static 修饰,不可再次赋值,只有 static 修饰可再次赋值。
  • 可访问表达式外层的 final 局部变量(不用声明为 final,隐性具有 final 语义),不可再次赋值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值