jdk1.8新特性之lamada表达式

本文深入探讨Java 8中引入的Lambda表达式,解释其概念、用途及结构,对比传统编程方式的优势,并详细说明如何在代码中应用,包括与函数式接口的结合使用。

什么是lamada表达式

Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确,但现在姑且这么认为),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。

它可以作为函数参数、函数返回值赋值给变量。

为什么用lamada表达式

在函数式编程语言中,函数是一等公民,它们可以独立存在,你可以将其赋值给一个变量,或将他们当做参数传给其他函数。JavaScript 是最典型的函数式编程语言。函数式语言提供了一种强大的功能——闭包,相比于传统的编程方法有很多优势,闭包是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。Java 现在提供的最接近闭包的概念便是Lambda 表达式,虽然闭包与 Lambda 表达式之间存在显著差别,但至少 Lambda 表达式是闭包很好的替代者。

Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待。尽管不完全正确,我们很快就会见识到 Lambda 与闭包的不同之处,但是又无限地接近闭包。在支持一类函数的语言中,Lambda 表达式的类型将是函数。但是,在 Java 中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface)。我们会在后文详细介绍函数式接口。

lamada表达式结构

Java 中的 Lambda 表达式通常使用 (argument) -> {body}语法书写,例如:

(arg1, arg2...) -> { body }
 
(type1 arg1, type2 arg2...) -> { body }
(a) -> System.out.println(a);

a -> System.out.println(a);

a -> { System.out.println(a); };

(String a) -> { System.out.println(a); };
 
() -> System.out.println("Hello World");

(int a, int b) -> System.out.println(a + b);
  • 一个 Lambda 表达式可以有零个或多个参数
  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同
  • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
  • 空圆括号代表参数集为空。例如:() -> 42
  • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
  • Lambda 表达式的主体可包含零条或多条语句
  • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返- 回类型与该主体表达式一致
  • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

函数式接口

lamada表达式是基于函数式接口上的基础上实现的。函数式接口是有且仅有一个抽象方法声明的接口。
这是两种new线程的方法,new Thread()需要的参数为Runnable接口实例对象。但是Runnable是一个接口,我们无法直接创建其对象,必须要先实现其抽象方法run()。jdk1.8之前我们的做法是匿名内部类或者新建Runnable的实现类。1.8引入了lamada表达式之后,我们对Runnable实现方法修改为下面代码中的方法。

// 非lamada表达式写法(匿名内部类)
new Thread(new Runnable() {
    @Override
    public void run() {
        
    }
}).start();

// lamada表达式写法
new Thread(() -> System.out.println("hello world")).start();

但是,并不是所有的接口都是可以通过lamada表达式去进行实现的。其中的原因就是jdk1.8函数式接口加入。进入Runnable接口的源代码可以看到
@FunctionalInterface这个注解,通过这个注解可以声明Runnable接口是一个函数式接口。该注解声明后,才可以使用lamada表达式对原来的代码进行替换。

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

@FunctionalInterface注解必须声明在接口上,且接口有且仅有一个抽象方法,否则都后在编译阶段报错。通过@FunctionalInterface注解,我们可以定义一个函数式接口,使用lamada表达式对其方法进行实现。
如下代码,执行main方法会打印“haha”。

package io.yjff.lmada;

/**
 * <函数式接口>
 * @FunctionalInterface只能修饰有且仅有一个抽象方法的接口,否则都会编译报错
 *
 * @author 刘远杰
 * @email 2634443725@qq.com
 * @since 1.0 2020/5/15
 */
@FunctionalInterface
public interface TestClass1Interface {

    void method1();
    
//    void method2();

}
public static void main(String[] args) {
      demo3();
}
    
public static void demo3() {
   /**
     * lamada表达式
     */
    execute(() -> System.out.println("haha"));
}

public static void execute(TestClass1Interface worker) {
     worker.method1();
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值