Java Lambda 表达式介绍

简介: Lambda 表达式是 Java SE8 推出的新功能,也是Java第一次引入函数式编程的尝试。Lambda表达式格式Lambda 表达式可以看做是一种匿名函数,但是它没有访问修饰符、返回值和名字。Lambda表达式由两部分构成,形式参数和方法体,中间用“->”符号分隔。其中的形式参数类型能够进行自动推断,可以不写。当然在某些特殊情况下,形参类型也是不可缺少的。

Lambda 表达式是 Java SE8 推出的新功能,也是Java第一次引入函数式编程的尝试。

Lambda表达式格式

Lambda 表达式可以看做是一种匿名函数,但是它没有访问修饰符、返回值和名字。Lambda表达式由两部分构成,形式参数和方法体,中间用“->”符号分隔。其中的形式参数类型能够进行自动推断,可以不写。当然在某些特殊情况下,形参类型也是不可缺少的。方法体可以是简单的表达式或者代码块,下面是一些例子:

// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)

函数式接口

函数式接口

要理解Lambda表达式,首先要了解一种特殊的接口:函数式接口。什么是函数式接口呢?简单来说就是只包含一个抽象方法的接口。Java标准库中的java.lang.Runnablejava.util.Comparator就是典型的函数式接口。对于函数式接口,我们就可以使用Lambda表达式来代替用传统匿名类来创建实例对象。

我们以Runnable接口为例,用传统匿名类的方式创建一个线程:

public void runThread() {
    new Thread(new Runnable() {
        public void run() {
            System.out.println("Run!");
        }
    }).start();
}

上面传统匿名类方式中,我们可以看到,我们需要new一个接口名称,接口内部还要附带这个接口抽象方法的实现。而如果我们使用Lambda表达式,则代码非常简洁:

public void runThreadUseLambda() {
    new Thread(() -> {
        System.out.println("Run!");
    }).start();
}

通过上面代码我们可以看到,Lambda表达式在两方面做了简化:

  • 首先不需要声明Runnable接口,因为这可以通过上下文推断出来
  • 其次不需要再写一个run方法的实现,因为函数式接口中只有一个方法

java.util.function包

在Java SE8之前标准库中的函数式接口并不多。JavaSE8增加了java.util.function包,里面都是可以在开发中只用的函数式接口。我们也可以自定义一个函数式接口,但最好在接口上使用@FunctionalInterface注解标明这是一个函数式接口,以免团队其它成员错误地往接口添加新的方法,当然java.util.function包中的所有接口都添加了@FunctionalInterface注解。

下面代码使用函数式接口java.util.Function接口实现的对列表map进行操作的方法,从代码中可以看出,如果使用函数式编程,代码看起来会非常简洁:

public class CollectionUtils {
    public static  List map(List input, Function processor) {
        ArrayList result = new ArrayList();
        for (T obj : input) {
            result.add(processor.apply(obj));
        }
        return result;
    }

    public static void main(String[] args) {
        List input = Arrays.asList(new String[] {"apple", "orange", "pear"});
        List lengths = CollectionUtils.map(input, (String v) -> v.length());
        List uppercases = CollectionUtils.map(input, (String v) -> v.toUpperCase());
    }
}

自定义函数式接口及@FunctionalInterface注解

注解可以起到指示、约束作用,关于注解大家可以参考 Java 注解详解 (annotation)。Java 8 为函数式接口新提供了@FunctionalInterface注解,当用注解的接口不是有效的函数式接口时,也就是接口中不只有一个抽象方法时,编译器会报编译错误。我们自定义一个函数式接口,并用@FunctionalInterface进行注解

@FunctionalInterface
public interface MyFunction {
    public void doSomething();
}

如果我们在上面接口中再加一个抽象方法:

@FunctionalInterface
public interface MyFunction {
    public void doSomething();
    public void doAnotherThing();
}

由于自定义接口中出现了两个抽象方法,不符合函数式接口定义,此时会抛出编译错误。我们再测一下上面这个自定义函数式接口:

public class TestMyFunction {
    public static void execute(MyFunction worker) {
        worker.doSomething();
    }
    public static void main(String [] args) {
        //传统匿名类的方式调用
        execute(new MyFunction() {
            public void doSomething() {
                System.out.println("Worker invoked using Anonymous class");
            }
        });
        //通过Lambda表达式调用
    execute( () -> System.out.println("Worker invoked using Lambda expression") );
    }
}
目录
相关文章
|
前端开发 数据挖掘 BI
氚云丨开发课— 03 氚云子表的常见操作| 学习笔记
快速学习氚云丨开发课— 03 氚云子表的常见操作。
氚云丨开发课— 03 氚云子表的常见操作| 学习笔记
|
Java 关系型数据库 MySQL
【实训项目】基于JavaWeb的图书销售购物系统
【实训项目】基于JavaWeb的图书销售购物系统
286 0
|
7月前
|
算法 数据安全/隐私保护 索引
基于GWO灰狼优化的多目标优化算法matlab仿真
本程序基于灰狼优化(GWO)算法实现多目标优化,适用于2个目标函数的MATLAB仿真。使用MATLAB2022A版本运行,迭代1000次后无水印输出结果。GWO通过模拟灰狼的社会层级和狩猎行为,有效搜索解空间,找到帕累托最优解集。核心步骤包括初始化狼群、更新领导者位置及适应值计算,确保高效探索多目标优化问题。该方法适用于工程、经济等领域复杂决策问题。
|
10月前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
275 4
|
12月前
|
Oracle 关系型数据库
oracle的start with connect by prior如何使用 整理
oracle的start with connect by prior如何使用 整理
759 4
|
消息中间件 缓存 监控
go-zero微服务实战系列(六、缓存一致性保证)
go-zero微服务实战系列(六、缓存一致性保证)
|
12月前
|
弹性计算 网络协议 API
原生Claude3免魔法本地轻松上手,这3步你必须要知道
本文详细介绍了如何在阿里云ECS上部署LobeChat,并通过Cloudflare实现Claude3 API的代理访问。首先准备ECS、Claude3 API密钥及域名,接着通过Docker部署LobeChat,并配置相关环境变量。然后,在Cloudflare上创建站点并部署API代理,最后通过SSH端口映射在本地访问LobeChat。文中提供了具体步骤与示例代码,帮助读者顺利完成部署,体验高效便捷的AI聊天功能。
1533 2
|
数据安全/隐私保护
阿里云智能媒体服务IMS
【2月更文挑战第22天】阿里云智能媒体服务IMS
254 7
|
存储 编译器 内存技术
【计算机组成原理】中央处理器
【计算机组成原理】中央处理器
519 1
【计算机组成原理】中央处理器
|
机器学习/深度学习 存储 人工智能
AI在数学界的作用和影响
众所周知,数学在科学中占据至关重要的地位。爱因斯坦曾说,“纯数学能使我们发现概念和联系这些概念的规律,给了我们理解自然现象的钥匙。数学之所以比一切其它科学受到尊重,一个理由是因为它的命题是绝对可靠的,无可争辩的,而其它的科学经常处于被新发现的事实推翻的危险。”那么,AI在数学界有哪些作用?AI未来对数学界会有哪些颠覆性影响?现在我们来进行论述和探讨。
527 0

热门文章

最新文章