从入门到精通:Java Lambda运算符详解!

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在Java 8之前,使用匿名类实现接口是一种常见的编程方式。但是,这种方式往往代码冗长且难以阅读。Java 8引入了Lambda表达式,它提供了一种更简洁的方式来实现接口。Lambda表达式通常是匿名函数(未命名的函数),可以作为参数传递给方法或存储在变量中。在本文中,我们将讨论Lambda表达式的语法、源代码解析、应用场景案例、优缺点分析以及类代码方法介绍。

摘要

  本文将介绍Lambda表达式的基本语法和使用方法,包括源代码解析和应用场景案例。我们还将分析Lambda表达式的优点和缺点,并提供一些测试用例,以帮助读者更好地理解和应用Lambda表达式。

Java之Lambda运算符

简介

  Lambda表达式是Java 8中最重要的新功能之一。它提供了一种简洁而灵活的方式来表示未命名的函数。在Java中,Lambda表达式通常被认为是Java 8中的函数式编程的基础。Lambda表达式的基本语法如下:

(parameters) -> expression

或者

(parameters) -> { statements; }

  其中,parameters是Lambda表达式的参数列表,expression或statements是Lambda表达式的函数体。与常规方法不同,Lambda表达式没有名称。

  Lambda表达式的参数可以为空,也可以包含一个或多个参数。如果参数列表中只有一个参数,则可以省略参数列表的括号。例如:

x -> x + 1 // 接受一个整数参数并返回此参数加1的结果

  Lambda表达式的主要优势在于它提供了一种更简洁的方式来实现接口。在Java 8中,Lambda表达式可以用来实现任何只有一个抽象方法的接口。这种接口被称为函数接口,可以使用@FunctionalInterface注解进行标记。

源代码解析

  让我们来看一个简单的Lambda表达式示例,该示例将接收一个名为names的字符串数组,并将其中的所有元素都转换为大写:

String[] names = {"Alice", "Bob", "Charlie"};
List<String> nameList = Arrays.asList(names);
nameList.stream().map(name -> name.toUpperCase()).forEach(System.out::println);

  在这个例子中,我们使用数组创建了一个名为names的字符串数组,并使用Arrays.asList()方法将其转换为List类型的集合。然后,我们将集合中的每个元素全部转换成大写,并使用forEach()方法对其进行输出。

  从语法上来说,Lambda表达式实际上是一个对象。在Java中,Lambda表达式通常编译成类似于匿名内部类的形式。每个Lambda表达式都有一个与之关联的接口类型,该接口只包含一个未实现的方法。编译器会根据Lambda表达式的参数和返回类型来推断其关联的接口类型。

  下面是一个简单的示例,演示了编写Lambda表达式的过程。

public class LambdaTest {public static void main(String[] args) {// 无参数的Lambda表达式Runnable r = () -> System.out.println("Hello World");r.run();// 有一个参数的Lambda表达式Consumer<String> consumer = (s) -> System.out.println(s);consumer.accept("Hello World");// 有两个参数的Lambda表达式BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;System.out.println(sum.apply(1, 2));}
}

  在这个例子中,我们创建了三个Lambda表达式,其中第一个表达式是一个无参数的Runnable接口实现。第二个表达式使用了一个参数的Consumer接口,该接口接受一个字符串并打印它。第三个表达式使用一个返回整数的BiFunction接口。

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

在这里插入图片描述

代码解析:

  这段代码演示了Lambda表达式的使用,具体分析如下:

  1. 定义了一个无参数的Lambda表达式,使用函数式接口Runnable,通过Lambda表达式实现了run()方法,输出字符串"Hello World"。

  2. 定义了一个有一个参数的Lambda表达式,使用函数式接口Consumer,通过Lambda表达式实现了accept()方法,将传入的字符串打印输出。

  3. 定义了一个有两个参数的Lambda表达式,使用函数式接口BiFunction<T, U, R>,通过Lambda表达式实现了apply()方法,对传入的两个整型数进行相加操作,返回结果。

  在main()方法中,分别创建了这三个Lambda表达式的实例,并分别调用对应的方法输出结果。

应用场景案例

  Lambda表达式可以应用于许多场景。下面是一些常见的应用场景:

  • 集合API:通过使用Lambda表达式,我们可以轻松地对集合中的元素进行过滤、转换和提取等操作。
  • GUI事件处理程序:在JavaFX和Swing等图形用户界面中,可以使用Lambda表达式作为事件处理程序。
  • 并行编程:在Java 8中,我们可以使用Lambda表达式来编写并行代码,从而实现更高效的代码执行。

  下面是一些常见的Lambda表达式应用场景示例:

  • 使用Lambda表达式过滤集合中的元素:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream().filter(name -> name.startsWith("A")).forEach(System.out::println);
  • 使用Lambda表达式对集合中的元素进行转换:
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream().map(name -> name.toUpperCase()).forEach(System.out::println);
  • 使用Lambda表达式作为事件处理程序:
Button button = new Button("Click me");
button.setOnAction(event -> System.out.println("Button clicked"));

代码解析:

  第一个代码示例是使用Lambda表达式对集合进行筛选,使用了Stream API中的filter方法,其中Lambda表达式中使用了startsWith()方法对字符串进行判断,筛选出以"A"开头的字符串并输出。

  第二个代码示例是使用Lambda表达式对集合中的元素进行转换,使用了Stream API中的map方法,其中Lambda表达式中使用了toUpperCase()方法将字符串转换为大写字母并输出。

  第三个代码示例是使用Lambda表达式作为事件处理程序,实现当按钮被点击时输出一条信息。其中Lambda表达式中的代码即为事件发生时要执行的代码。

优缺点分析

  Lambda表达式可以使代码更加简洁、易于阅读和维护。它可以减少代码量、提高程序的可读性和可维护性,同时还能提升程序的性能。Lambda表达式的主要优势在于它提供了一种更简洁的方式来实现接口。在Java 8中,Lambda表达式可以用来实现任何只有一个抽象方法的接口。这种接口被称为函数接口,可以使用@FunctionalInterface注解进行标记。

  然而,Lambda表达式不是完美的。它们可能导致代码变得更加难以理解,特别是在复杂的嵌套情况下。此外,如果Lambda表达式不当使用,可能会导致性能下降和代码可读性降低。

类代码方法介绍

  Lambda表达式可以用于实现函数式接口。下面是一些常见的函数式接口和Lambda表达式的示例:

  • Predicate接口
Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // 输出true
  • Function接口
Function<String, Integer> stringToInt = s -> Integer.parseInt(s);
System.out.println(stringToInt.apply("123")); // 输出123
  • Consumer接口
Consumer<String> printer = s -> System.out.println(s);
printer.accept("Hello World"); // 输出Hello World

代码解析:

  这三个接口都是Java函数式接口,都是Java 8之后引入的,可以用lambda表达式或方法引用来创建函数对象。它们的作用分别如下:

  • Predicate<T>:接收一个泛型参数,返回一个boolean值。用于测试给定的输入值是否符合某种条件,通常用于过滤集合中的元素。
  • Function<T, R>:接收一个泛型参数T,返回一个泛型参数R。用于将一个类型的值转换为另一个类型的值。
  • Consumer<T>:接收一个泛型参数,没有返回值。用于处理给定的输入值,通常用于对集合中的元素执行某些操作。

  在分别实例化了这三个接口之后,可以使用它们提供的方法来执行对应的操作。对于Predicate,可以使用test()方法测试输入值是否符合条件;对于Function,可以使用apply()方法将输入值转换为输出值;对于Consumer,可以使用accept()方法来处理输入值。

测试用例

测试代码演示

package com.example.javase.se.operators;import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;/*** Java之Lambda运算符实例演示** @Author ms* @Date 2023-11-08 11:13*/
public class LambdaDemo {public static void main(String[] args) {List<String> names = Arrays.asList("Alice", "Bob", "Charlie");// 没有参数的Lambda表达式Runnable r = () -> System.out.println("Hello World");r.run();// 有一个参数的Lambda表达式Consumer<String> printer = s -> System.out.println(s);printer.accept("Hello World");// 有两个参数的Lambda表达式BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;System.out.println(sum.apply(1, 2));// 过滤集合中的元素names.stream().filter(name -> name.startsWith("A")).forEach(System.out::println);// 将集合中的元素转换为大写names.stream().map(name -> name.toUpperCase()).forEach(System.out::println);}
}

测试结果

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

在这里插入图片描述

测试代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。
  该代码演示了Lambda运算符在Java中的使用。Lambda表达式是一种匿名函数,可以作为参数传递给其他方法或函数。Lambda表达式的语法如下:

(parameter1, parameter2, ..., parameterN) -> { statement1; statement2; ... statementN; }

  Lambda表达式的参数可以是0个、1个或多个,类型也可以省略。在示例代码中,展示了Lambda表达式的三种形式:

  1. 没有参数的Lambda表达式:使用Runnable接口创建一个线程并使用Lambda表达式作为其运行代码。

  2. 有一个参数的Lambda表达式:将一条消息作为参数传递给一个消费者函数并使用Lambda表达式打印出来。

  3. 有两个参数的Lambda表达式:将两个整数相加并返回它们的和。

  此外,代码还使用了Java 8中的流API对列表中的元素进行过滤和转换。在过滤集合中元素的示例中,使用了Lambda表达式作为Predicate函数实现,过滤出以字母“A”开头的字符串。在将集合中的元素转换为大写的示例中,使用了Lambda表达式作为Function函数实现,将每个元素转换为大写并打印出来。

全文小结

  首先我们介绍了Lambda表达式的语法、源代码解析、应用场景案例以及优缺点分析。Lambda表达式的语法非常简洁,它可以用来实现任何只有一个抽象方法的接口,这种接口被称为函数接口。

  接着,介绍了Lambda表达式的应用场景,并通过几个代码示例演示了Lambda在集合API、GUI事件处理程序和并行编程中的应用。

  分析了Lambda表达式的优缺点,指出了Lambda表达式可以使代码更加简洁、易于阅读和维护,但也可能会导致代码变得更加难以理解,特别是在复杂的嵌套情况下。

  最后,文章介绍了一些常见的函数式接口和Lambda表达式的示例,并提供了一个包含测试用例的完整代码示例。

  总体来说,本文内容丰富,适合对Lambda表达式感兴趣的Java开发者。

总结

  本文介绍了Java中Lambda表达式的基本语法、源代码解析、应用场景案例、优缺点分析以及类代码方法介绍等内容。Lambda表达式是Java 8中最重要的新功能之一,提供了一种简洁而灵活的方式来表示未命名的函数,可以使代码更加简洁、易于阅读和维护。Lambda表达式的主要优势在于它提供了一种更简洁的方式来实现接口。在Java 8中,Lambda表达式可以用来实现任何只有一个抽象方法的接口,这种接口被称为函数接口。Lambda表达式的应用场景包括集合API、GUI事件处理程序和并行编程等。但是,Lambda表达式也可能会导致代码变得更加难以理解,特别是在复杂的嵌套情况下。本文还提供了一些常见的函数式接口和Lambda表达式的示例,并提供了一个包含测试用例的完整代码示例。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23791.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣 503. 下一个更大元素 II

题目来源&#xff1a;https://leetcode.cn/problems/next-greater-element-ii/description/ C题解&#xff1a;因为是循环数组&#xff0c;所以对数组进行了两次遍历&#xff0c;相当于循环。使用了栈&#xff0c;一个存放元素&#xff0c;一个存放索引&#xff0c;用来更新res…

【C++ | 析构函数】类的析构函数详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-06-06 1…

使用MFC DLL

本文仅供学习交流&#xff0c;严禁用于商业用途&#xff0c;如本文涉及侵权请及时联系本人将于及时删除 应用程序与DLL链接后&#xff0c;DLL才能通过应用程序调用运行。应用程序与DLL链接的方式主要有如下两种&#xff1a;隐式链接和显式链接。 隐式链接又称为静态加载&…

Linux常见故障处理之df命令卡住不输出

一、背景说明 朋友咨询Linux系统下输入df -h命令后没有任何输出结果&#xff0c;博主的第一反应是/根分区磁盘空间满了&#xff0c;朋友说cd等其他命令可以执行。博主又猜测可能是有人误定义了命令别名&#xff0c;进一步确认命令卡住在等待输出页面。事后博主想起来可能是共享…

[AIGC] “从入门到实践:使用Mockito优雅地处理Java单元测试“

当需要测试的接口依赖多个其他的接口时&#xff0c;我们依旧可以使用Mockito来进行处理。这时候&#xff0c;我们通常会使用到Mockito的InjectMocks和Mock注解。 下面提供一个例子&#xff0c;这个例子描述了一个BookService类&#xff0c;它依赖于另外两个接口&#xff1a;Bo…

C++ 反转单词

在C中&#xff0c;反转一个字符串中的单词&#xff08;单词之间通过空格分隔&#xff0c;但单词内部保持原有顺序&#xff09;可以通过以下步骤实现&#xff1a; 找到字符串中的所有单词&#xff0c;这可以通过查找空格来实现。将单词存储在一个容器中&#xff08;例如 std::v…

代码随想录——删除二叉搜索树中的节点(Leetcode450)

题目链接 递归 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

4-护网需要具备的技能

红队&#xff1a; 外围打点能力漏洞挖掘能力漏洞分析能力权限提升能力权限维持能力钓鱼远控能力代码审计能力木马免杀能力内网渗透能力横向移动能力域渗透能力跨域渗透能力 蓝队&#xff1a; 设备使用能力设备监控能力研判分析能力攻击辨别能力流量分析能力入侵排查能力日志…

RapidJSON

要在项目中使用 RapidJSON 库&#xff0c;需要首先下载并包含该库的头文件。以下是详细的步骤&#xff0c;包括如何下载、引用和使用 RapidJSON&#xff1a; 使用 CMake 引用 RapidJSON 如果你的项目使用 CMake 构建系统&#xff0c;可以按照以下步骤引用 RapidJSON&#xff…

终极GPU互联技术探索:消失的内存墙

一、引言 随着人工智能、大数据、云计算等技术的飞速发展&#xff0c;计算能力的需求呈现出爆炸性增长。在这个背景下&#xff0c;图形处理器&#xff08;GPU&#xff09;凭借其强大的并行计算能力&#xff0c;在深度学习、科学计算等领域扮演着越来越重要的角色。然而&#x…

用Pip配置Pytorch环境 (Pytorch==2.3.0)

用Pip配置Pytorch环境 (Pytorch2.3.0) 本文主要讲解: 如何用Conda搭建Pytorch环境&#xff0c;用Conda的方式安装&#xff0c;需要单独去安装Cuda。 1. 下载Python安装包 安装Python 3.10.11&#xff0c;下载地址 Python 3.10.11 2. CUDA 安装 安装CUDA 12.1&#xff0c; …

JavaSE—泛型

1 泛型定义和基本使用 泛型是JDK1.5以后才有的&#xff0c; 可以在编译时期进行类型检查&#xff0c;且可以避免频繁类型转化&#xff01; Test public void test1() {List list new ArrayList();list.add("ZhangSan");list.add(1);//集合使用 取出元素Object obj…

R语言数据探索和分析22-使用随机森林和聚类算法探索和预测健康状况

一、研究背景 在两个实验中&#xff0c;使用了一组综合性的生物统计数据来探索和预测健康状况&#xff08;特别是疾病的发生&#xff09;。实验的核心在于应用高级数据分析技术&#xff0c;具体包括随机森林分类和聚类分析&#xff0c;来洞察和预测个体的健康状况。首先&#…

【十大排序算法】选择排序

选择就像是在谱曲&#xff0c;每个决定就是一个音符&#xff0c;只有将它们有序地安排在一起&#xff0c;才能奏响美妙的乐章。 文章目录 一、选择排序的思想二、选择排序的发展历程三、选择排序具象化四、选择排序算法实现五、选择排序的特性推荐阅读 一、选择排序的思想 选…

Kafka初步学习

kafka消息队列模式 点对点模式&#xff1a;一对一&#xff0c;消费者主动拉取数据&#xff0c;消息收到后消息清除 消息生产者生产消息发送到queue中&#xff0c;然后消息消费者从queue中取出并且消费消息 消息被消费以后&#xff0c;queue中不再有存储&#xff0c;所以消息消费…

【DevOps】网站安全事件分析方法详解和实战分析

目录 一、网站安全事件分析流程 二、常用的网站安全事件分析方法 三、网站被植入挖矿脚本事件分析 1、 事件发现与确认 2、 事件隔离与取证 3、 事件分析与溯源 4、 事件处置与恢复 5、 事件总结与改进 四、网站安全事件分析的关键点 五、提高网站安全事件分析能力的…

python使用appium截图手机屏幕图片

要使用 Appium 截取手机屏幕图片并在电脑上显示&#xff0c;你需要执行几个步骤。以下是一个基本的流程&#xff1a; 设置 Appium 环境&#xff1a;确保你已经安装了 Appium 服务器和 Python 客户端库&#xff08;如 appium-python-client&#xff09;。编写 Python 脚本&…

详解大厂实时数仓建设V4.0

一、实时数仓建设背景 1. 实时需求日趋迫切 目前各大公司的产品需求和内部决策对于数据实时性的要求越来越迫切&#xff0c;需要实时数仓的能力来赋能。传统离线数仓的数据时效性是 T1&#xff0c;调度频率以天为单位&#xff0c;无法支撑实时场景的数据需求。即使能将调度频…

参数传递和剪枝,从修剪二叉树谈起

669. 修剪二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 一、参数传递 Java中的参数传递方式只有一种&#xff0c;那就是值传递。如果我们传的是基本数据类型&#xff0c;那么函数接收到的就是该数据的副本&#xff0c;如果我们传的是对象&#xff0c;那么函数接收到的就…

Uniapp与第三方应用数据通讯

首先说明一点&#xff0c;这个只是uniapp代码编写的应用之间相互传递数据&#xff0c;uniapp编写的与其他语言编写的我尚不知道能不能传递。 应用1&#xff1a; plus.runtime.launchApplication({pname: "应用的appid",// extra 中可以自定数据&#xff0c;url和da…