一文带你看懂Java8中的lambda表达式和方法引用

 更新时间:2023年12月05日 08:49:00   作者:星夜晚晚  
Lambda 表达式是 Java 8 引入的一项重要特性,它提供了一种简洁、清晰且灵活的语法来表示可传递的匿名函数,下面就跟随小编一起学习一下Java8中的lambda表达式和方法引用的相关知识吧

上一篇文章介绍Consumer接口时讲到lambda表达式和方法引用,这里顺便将这两个讲一下。

Lambda 表达式是 Java 8 引入的一项重要特性,它提供了一种简洁、清晰且灵活的语法来表示可传递的匿名函数。Lambda 表达式是一种语法糖,提供了一种更简洁的语法来实例化函数式接口(Functional Interface)。

基本语法

Lambda 表达式的基本语法如下:

(parameters) -> expression

(parameters) -> { statements; }

其中:

  • parameters 指的是 Lambda 表达式的参数列表。
  • -> 是 Lambda 运算符,它将参数列表与 Lambda 表达式的主体分开。
  • expression 是 Lambda 表达式的返回表达式。
  • {} 内包含了 Lambda 表达式的代码块,可以包含多个语句。

示例

以下是一些 Lambda 表达式的示例:

不带参数的 Lambda 表达式:

() -> System.out.println("Hello, Lambda!");

带参数的 Lambda 表达式:

(int x, int y) -> x + y

带参数和代码块的 Lambda 表达式:

(String s) -> {
    System.out.println(s);
    // 可以包含多个语句
}

使用场景

Lambda 表达式通常用于函数式接口的实例化,即接口中只有一个抽象方法的情况。例如,RunnableCallableComparator 等接口都是函数式接口,可以通过 Lambda 表达式来实例化。

// 使用 Lambda 表达式实例化 Runnable
Runnable myRunnable = () -> System.out.println("Hello, Lambda!");

// 使用 Lambda 表达式实例化 Comparator
Comparator<String> myComparator = (s1, s2) -> s1.compareTo(s2);

本质

虽然 Lambda 表达式的语法看起来像是一个函数,但实际上它在 Java 中被实现为一个对象,是一个匿名的内部类对象。这个对象的类型是由编译器根据上下文和目标类型进行推导的。这个对象可以被赋值给相应的函数式接口。 在讲Consumer接口时,我们的一个例子。

import java.util.function.Consumer;

public class ConsumerExample {

    public static void main(String[] args) {
        // 创建一个Consumer实例
        Consumer<String> myConsumer = s -> System.out.println(s);

        // 使用Consumer的accept方法
        myConsumer.accept("Hello, Consumer!");
    }
}

首先s -> System.out.println(s)是lambda表达式,本质是一个只含有一个方法的匿名内部类对象。它的演化流程是,定义一个函数式接口

interface MyFunctionalInterface {
    void myMethod(String s);
}

然后使用匿名内部类(这个内部类实现这个函数式接口,编写抽象方法的逻辑),并实例化这个对象,由于java的多态特点,父类引用可以指向子类对象,因此父类引用MyFunctionalInterface可以指向新的接口实例化后的对象。

MyFunctionalInterface myFunction = new MyFunctionalInterface() {
    @Override
    public void myMethod(String s) {
        // 实现接口中的方法,比如
        System.out.println(s);
    }
};

这样的写法弊端是语法冗长,代码显得不够简洁。Lambda 表达式的引入就是为了解决这个问题,让代码更加紧凑和易读。使用 Lambda 表达式,上面的代码可以被简化为:

MyFunctionalInterface myFunction =(String s)-> System.out.println(s);

当 Lambda 表达式只有一个参数时,可以省略参数的括号。而且当上下文可以推断出类型时,参数的类型也可以省略。最终变为:

 Consumer<String> myConsumer = s -> System.out.println(s);

java泛型来推断s的类型为String

Consumer本身就是一个函数式接口,所以此处System.out.println(s)就是Consumer中抽象方法accept的实现逻辑。示例中的MyFunctionalInterface其实就是Consumer,或者经过编译器推断,这个函数式接口就是Consumer

方法引用

Lambda 表达式的一个变体是方法引用,它允许你直接引用已有的方法。例如:

// 使用静态方法引用
Function<String, Integer> toInt = Integer::parseInt;

// 使用实例方法引用
List<String> list = Arrays.asList("1", "2", "3");
list.forEach(System.out::println);

这里 Integer::parseInt 是一个静态方法引用,System.out::println 是一个实例方法引用。

有四种主要的方法引用的形式:

静态方法引用(Static Method Reference): ClassName::staticMethodName

实例方法引用(Instance Method Reference):

  • 对于特定对象的实例方法:instance::instanceMethodName
  • 对于任意对象的实例方法:ClassName::instanceMethodName

构造方法引用(Constructor Reference): ClassName::new

数组构造方法引用(Array Constructor Reference): TypeName[]::new

Lambda 表达式的优势

  • 简洁性: Lambda 表达式可以减少冗余的代码,使代码更加简洁和易读。
  • 函数式编程: 提供了函数式编程的支持,使得在Java中更容易使用函数作为一等公民。
  • 并行处理: 可以更容易地实现并行处理,通过并行流等特性,提高程序的性能。

Lambda 表达式是 Java 8 引入的一项重要特性,它在编写简洁、清晰的代码和支持函数式编程方面起到了关键作用。方法引用是Lambda 表达式的变体。

以上就是一文带你看懂Java8中的lambda表达式和方法引用的详细内容,更多关于Java8 lambda表达式的资料请关注脚本之家其它相关文章!

相关文章

  • SpringBoot实现kafka多源配置的示例代码

    SpringBoot实现kafka多源配置的示例代码

    实际开发中,不同的topic可能来自不同的集群,所以就需要配置不同的kafka数据源,基于springboot自动配置的思想,最终通过配置文件的配置,自动生成生产者及消费者的配置,本文介绍了SpringBoot实现kafka多源配置,需要的朋友可以参考下
    2024-06-06
  • Java 添加、删除、替换、格式化Word中的文本的步骤详解(基于Spire.Cloud.SDK for Java)

    Java 添加、删除、替换、格式化Word中的文本的步骤详解(基于Spire.Cloud.SDK for Java)

    这篇文章主要介绍了Java 添加、删除、替换、格式化Word中的文本(基于Spire.Cloud.SDK for Java),本文分步骤通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • SpringSecurity整合springBoot、redis实现登录互踢功能

    SpringSecurity整合springBoot、redis实现登录互踢功能

    这篇文章主要介绍了SpringSecurity整合springBoot、redis实现登录互踢,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • SpringMVC一步到位精通拦截器

    SpringMVC一步到位精通拦截器

    拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。本文将详细讲讲SpringMVC中拦截器的概念及入门案例,感兴趣的可以尝试一下
    2022-12-12
  • SpringBoot入门实现第一个SpringBoot项目

    SpringBoot入门实现第一个SpringBoot项目

    今天我们一起来完成一个简单的SpringBoot(Hello World)。就把他作为你的第一个SpringBoot项目。具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09
  • Java实现桌面日历

    Java实现桌面日历

    这篇文章主要为大家详细介绍了Java实现桌面日历,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • java定长队列的实现示例

    java定长队列的实现示例

    定长队列是一种有限容量的队列,对于某些应用场景非常有用,本文主要介绍了java定长队列的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • Java实现Ip地址获取的示例代码

    Java实现Ip地址获取的示例代码

    这篇文章主要为大家详细介绍了Java实现Ip地址获取的两种方式,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2023-09-09
  • JVM解密之解构类加载与GC垃圾回收机制详解

    JVM解密之解构类加载与GC垃圾回收机制详解

    本文主要介绍了Java虚拟机(JVM)的内存划分、类加载机制以及垃圾回收机制,JVM的内存划分为程序计数器、栈、堆和方法区,类加载机制包括类加载过程、加载器模型和双亲委派模型,垃圾回收机制主要包括标记-清除、标记-复制、标记-整理和分代回收算法
    2025-02-02
  • Springboot项目与vue项目整合打包的实现方式

    Springboot项目与vue项目整合打包的实现方式

    这篇文章主要介绍了Springboot项目与vue项目整合打包的实现方式,本文通过两种方式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07

最新评论