Java中Lambda表达式的使用

news2025/1/24 18:03:36

Lambda的背景

Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。 Lambda 表达式(Lambda expression),基于数学中的λ演算得名,也可称为闭包(Closure) 。

Lambda表达式的语法

基本语法:

(parameters) -> expression 或 (parameters) ->{ statements; }


Lambda表达式由三部分组成:

  • 1. paramaters:类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明
  • 也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。
  • 2. ->:可理解为“被用于”的意思
  • 3. 方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不反回。

// 1. 不需要参数,返回值为 2
() -> 2
// 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表达式的使用的时候我们先来介绍函数式接口,这有助于我们快速了解Lambda表达式。

在Java中,函数式接口是指仅包含一个抽象方法的接口,它可以被隐式转换为一个 lambda 表达式或者方法引用。函数式接口的主要用途是支持函数式编程,使得代码更加简洁和易于阅读。

特点:

  1. 单一抽象方法:函数式接口只能有一个未实现的方法,这使得它可以表示单一的行为。
  2. 默认方法:虽然只能有一个抽象方法,但函数式接口可以包含多个默认方法和静态方法。
  3. @FunctionalInterface 注解:使用 @FunctionalInterface 注解可以清晰地表明一个接口是函数式接口,编译器会强制检查是否满足函数式接口的条件。

示例:

@FunctionalInterface
public interface MyFunctionalInterface {
    void execute();
    
    default void defaultMethod() {
        System.out.println("This is a default method.");
    }
    
    static void staticMethod() {
        System.out.println("This is a static method.");
    }
}

可以使用 lambda 表达式来实现这个函数式接口:

public class Main {
    public static void main(String[] args) {
        MyFunctionalInterface myFunc = () -> System.out.println("Executing...");
        myFunc.execute();  // 输出: Executing...
        
        myFunc.defaultMethod();  // 输出: This is a default method.
        MyFunctionalInterface.staticMethod();  // 输出: This is a static method.
    }
}

结论:

函数式接口是Java 8引入的重要特性,促进了函数式编程的实现,使得编写更加简洁和灵活的代码成为可能。

Lambda表达式的使用

基本语法

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

(parameters) -> expression

或者如果有多个语句:

(parameters) -> { statements } 

使用示例

下面的例子展示了如何在Java中使用Lambda表达式。

1. 定义函数式接口

首先,我们定义一个简单的函数式接口,该接口只有一个抽象方法:

@FunctionalInterface
public interface MyFunctionalInterface {
    void apply(String message);
}

2. 使用Lambda表达式

接下来,我们使用Lambda表达式来实现这个接口:

public class LambdaExample {
    public static void main(String[] args) {
        // 使用Lambda表达式实现MyFunctionalInterface接口
        MyFunctionalInterface myFunc = (message) -> System.out.println("Message: " + message);
        
        // 调用apply方法
        myFunc.apply("Hello, Lambda!");  // 输出: Message: Hello, Lambda!
    }
}

另一个示例:使用Lambda表达式进行集合操作

Lambda表达式常用于集合操作,特别是与 Stream API结合时。以下是一个使用Lambda表达式过滤和打印列表中所有以“A”开头的字符串的示例:

import java.util.Arrays;
import java.util.List;

public class LambdaStreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Amanda", "Charlie");

        // 使用Lambda表达式过滤以"A"开头的名字
        names.stream()
             .filter(name -> name.startsWith("A"))  // 过滤以“A”开头的名字
             .forEach(name -> System.out.println(name));  // 打印结果
    }
}

总结

Lambda表达式通过简化代码和减少冗余,使得函数式编程在Java中变得更加容易。它特别适用于实现函数式接口,提高了代码的可读性和简洁性。通过以上示例,我们可以看到Lambda表达式在实际应用中的基本使用方式。

 语法精简

  • 1. 参数类型可以省略,如果需要省略,每个参数的类型都要省略。
  • 2. 参数的小括号里面只有一个参数,那么小括号可以省略
  • 3. 如果方法体当中只有一句代码,那么大括号可以省略
  • 4. 如果方法体中只有一条语句,且是return语句,那么大括号可以省略,且去掉return关键字。

Lambda的变量捕获

在Lambda当中也可以进行变量的捕获,具体我们看一下代码。

@FunctionalInterface
interface NoParameterNoReturn {
   void test();
}
public static void main(String[] args) {
       int a = 10;
       NoParameterNoReturn noParameterNoReturn = ()->{
           System.out.println("捕获变量:"+a);
      };
       noParameterNoReturn.test();
}

 

 Lambda表达式在集合中的使用

在PriorityQueue中的使用

我们在使用PriorityQueue的时候经常要传一个比较器,如下:

public class Main {
    public static void main(String[] args) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });

    }
}

这时我们就可以用Lambda表达式来代替这个匿名内部类,如下代码:

public class Main {
    public static void main(String[] args) {
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1,o2)->{return o1 - o2;});
    }
}

这时就提高了代码的简洁性。

在 forEach 方法中的使用

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(1);
        list.add(6);
        list.add(4);
        list.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });
    }
}

这个方法的作用是遍历整个集合,在传参是的时候要使用 Consumer 这个接口,这时我们就可以利用Lambda表达式来简写代码了。如下:

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(1);
        list.add(6);
        list.add(4);
        list.forEach((a)-> System.out.println(a));
    }
}

在 sort 方法中使用 

sort 方法是将一个集合进行排序

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(1);
        list.add(6);
        list.add(4);
        list.forEach((a)-> System.out.println(a));

        System.out.println("=====");

        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
            }
        });

        list.forEach((a)-> System.out.println(a));
    }
}

用Lambda表达式简化代码

public class Main {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(3);
        list.add(1);
        list.add(6);
        list.add(4);
        list.forEach((a)-> System.out.println(a));

        System.out.println("=====");

        list.sort((o1,o2) -> {return o1 - o2;});

        list.forEach((a)-> System.out.println(a));
    }
}

 

总结

Lambda表达式的优点很明显,在代码层次上来说,使代码变得非常的简洁。缺点也很明显,代码不易读。
优点:

  • 1. 代码简洁,开发迅速
  • 2. 方便函数式编程
  • 3. 非常容易进行并行计算
  • 4. Java 引入 Lambda,改善了集合操作

缺点:

  • 1. 代码可读性变差
  • 2. 在非并行计算中,很多计算未必有传统的 for 性能要高
  • 3. 不容易进行调试 

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

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

相关文章

用户看广告获取密码访问网页内容流量主模式源码

简介&#xff1a; 全开源付费进群流量主模式&#xff0c;用户看广告获取密码访问网页内容&#xff0c;网站生成内容&#xff0c;用户需要浏览内容跳转至小程序&#xff0c;观看广告后获取密码&#xff0c;输入密码查看网页内容。 与之前得9.9付费进群区别就是内容体现在了网页…

【信创】国产操作系统上使用的万能打印驱动 _ 统信 _ 麒麟 _ 中科方德

往期好文&#xff1a;统信UOS服务器离线安装postgresql数据库 Hello&#xff0c;大家好&#xff01;今天给大家带来一款在信创终端操作系统上使用的万能打印驱动——瑞印万能打印驱动。这款驱动程序是国产操作系统下的通用打印驱动程序&#xff0c;具有很高的兼容性和广泛的功能…

图论:1857. 有向图中最大颜色值(拓扑排序+动态规划)

文章目录 1.问题分析2.代码解析2.1 代码步骤1. 初始化数据结构2. 构建图和入度数组3. 初始化队列4. 拓扑排序和动态规划5. 检查是否存在环并返回结果 3. 问题扩展1. 最长路径问题&#xff08;DAG&#xff09;2. 最短路径问题&#xff08;DAG&#xff09;3. 最大路径和问题4. 路…

科普文:微服务之Spring Cloud 客户端负载均衡组件LoadBalancer替代Ribbon

概叙 负载均衡 负载均衡的两个基本点&#xff1a; 选择哪个服务器来处理客户端请求。将客户端请求转发出去。 一个核心原理&#xff1a;通过硬件或软件的方式维护一个服务列表清单。当用户发送请求时&#xff0c;会将请求发送给负载均衡器&#xff0c;然后根据负载均衡算法从…

中仕公考:2024年重庆市属事业单位招聘公告

本次公开招聘市属事业单位工作人员218名&#xff0c;报考者可登录重庆市人力资源和社会保障局官网“事业单位公开招聘”栏查阅。 (一)可报考的条件 1.具有中华人民共和国国籍; 2.遵守中华人民共和国宪法和法律&#xff0c;具有良好的品行; 3.身体健康&#xff0c;符合事业单…

OGG同步目标端中文乱码处理

现象说明&#xff1a; 源端字符集&#xff1a;AMERICAN_AMERICA.ZHS16GBK 目标端字符集&#xff1a;AMERICAN_AMERICA.AL32UTF8 源端同步过来的数据显示中文乱码。 查询数据库表中含有乱码的字段&#xff1a; select * from xx.xxxx a where to_char(a.crtopetime,yyyy-mm-…

一些不被人熟知,但又很好用的HTML属性

HTML&#xff08;超文本标记语言&#xff09;具有多种属性&#xff0c;可用于增强我们的网页的结构和功能。 下面我就给大家介绍一下&#xff0c;一些很好用的HTML属性&#xff0c;但是不被人熟知的HTML属性 contenteditable&#xff1a; 这个属性使我们的元素变的可编辑。用…

谷粒商城实战笔记-126-全文检索-ElasticSearch-整合-测试保存

文章目录 一&#xff0c;谷粒商城实战笔记-126-全文检索-ElasticSearch-整合-测试保存1&#xff0c;在Elasticsearch的配置类中增加通用设置2&#xff0c;索引数据3&#xff0c;验证 一&#xff0c;谷粒商城实战笔记-126-全文检索-ElasticSearch-整合-测试保存 1&#xff0c;在…

环境搭建:全面详尽的 MongoDB Shell MongoDB Server介绍、安装、验证与配置指南(以 Windows 系统为主)

环境搭建&#xff1a;全面详尽的 MongoDB Shell & MongoDB Server介绍、安装、验证与配置指南&#xff08;以 Windows 系统为主&#xff09; MongoDB 是一个基于文档的 NoSQL 数据库&#xff0c;以其高性能、灵活性和可扩展性而受到广泛欢迎。本文将带您完成 MongoDB 的安装…

数据结构第十讲:二叉树OJ题

数据结构第十讲&#xff1a;二叉树OJ题 1.单值二叉树2.相同的树3.对称二叉树4. 另一棵树的子树5.二叉树的前序遍历6.二叉树的中序遍历7.二叉树的后序遍历8.二叉树的构建及其遍历9.二叉树选择题9.1二叉树性质19.2二叉树性质29.3二叉树性质三9.4选择题 1.单值二叉树 链接: OJ题链…

Java-----二叉树

1.树型结构 1.1概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看 起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#xff1a; 1.有…

本地文件上传

java本地文件上传 1、FileController /*** author: yc* des: 文件接口* date: 2024/8/4 11:11*/ RestController RequestMapping("/file") public class FileController {Resourceprivate FileService fileService;PostMapping("/upload")public Respon…

智能交通(6)——DQN代码复现

伪代码 如算法描述&#xff0c;dqn即深度q网络和记忆池 初始化记忆池和可以容纳的数量N 动作价值函数Q使用随机权重进行初始化。 目标动作价值函数Q′也使用相同的权重进行初始化&#xff0c;即Q′Q。 循环训练M局 初始化和预处理观察到的状态 每局循环训练T步 采用e的概…

【Scene Transformer】scene transformer论文阅读笔记

文章目录 序言(Abstract)(Introduction)(Related Work)(Methods)(Scene-centric Representation for Agents and Road Graphs)(Encoding Transformer)(Predicting Probabilities for Each Futures)(Joint and Marginal Loss Formulation) (Results)(Discussion)(Questions) sce…

Linux|最佳命令行下载加速器

引言 无论是远程工作还是本地工作&#xff0c;我们经常需要从外部获取信息。在没有其他选择的情况下&#xff0c;使用命令行工具来获取这些信息是一个不错的选择。 本文[1]将介绍一些通过命令行下载内容时最常使用的工具。 Wget 我们首先介绍一个广受欢迎的工具 wget。它是一个…

使用Qt编译modbus

一.编译库文件 1. 创建library项目 2. 选择要配置的编译器 3. 把自动生成的源码都移除&#xff1a;&#xff08;右键单击&#xff0c;选择 remove&#xff09; 4 4. 导入库源码 把源码拷贝到项目目录下&#xff08;.pro 文件所在的目录&#xff09; 5. 修改 configure.js 文…

(计算机网络)物理层

目录 一.基本概念 二.基本术语 三.码元 四.多路复用技术 一.基本概念 1. 2. 3. 4. 5. 6. 7. 8. 9. 二.基本术语 1. 2. 3.早期--公用的电话网传输数据&#xff0c;网络上传的是模拟信号&#xff0c;调制解调器--将数字信号转化成模拟信号&#xff0c;最后&#xff0c;调制解…

Java: 线程安全问题的解决方案(synchronized)

发生原因 要想解决线程安全问题,那么我们首先得知道线程安全问题为什么会发生. 发生原因: 线程在操作系统中是"随机调度,抢占式执行的"[根本原因].多个线程,同时修改同一个变量修改操作不是"原子"的内存可见性问题指令重排序 解决方案 原因1和2,我们很…

htsjdk库FeatureCodec和Feature接口介绍

在 HTSJDK 库中,FeatureCodec 接口和 Feature 接口分别扮演不同的角色,用于处理基因组数据的不同方面。下面是这两个接口的区别和各自的功能: FeatureCodec 接口 主要功能 编码和解码:FeatureCodec 接口的主要职责是定义如何将数据从文件格式解码为 Java 对象(即 Featur…

【C语言】分支与循环(循环篇)——结尾猜数字游戏实现

前言 C语言是一种结构化的计算机语言&#xff0c;这里指的通常是顺序结构、选择结构、循环结构&#xff0c;掌握这三种结构之后我们就可以解决大多数问题。 分支结构可以使用if、switch来实现&#xff0c;而循环可以使用for、while、do while来实现。 1. while循环 C语言中…