Lambda表达式及Stream的使用

前言:

    函数式编程是一种编程范式,它将计算过程视为函数应用的连续组合。函数式编程强调使用纯函数(Pure Function),避免使用可变状态和副作用,倡导将计算过程抽象为函数,便于代码的理解、测试和并行化。在JDK8之前主要函数式编程主要体现在匿名内部类的使用上。

Thread thread = new Thread(new Runnable() {public void run() {System.out.println("Hello from anonymous inner class");}
});
thread.start();

一、Lambda表达式

1.1 Lambda表达式的理解

      Lambda表达式是JAVA8提出的又一种函数式编程的体现,旨在提供一种更简洁的语法来表示函数式接口(只有一个抽象方法的接口)的实例。可以理解为  Lambda表达式就是对函数式接口实现的一种优化。

1.2 Lambda表达式的语法

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

(parameters) -> expression

   或

(parameters) -> { statements; }

        其中,参数可以是任意合法的Java参数列表,可以为空或包含一个或多个参数。箭头(->)将参数与Lambda主体分隔开来。

        Lambda主体可以是一个表达式,也可以是一个代码块。如果主体是一个表达式,它将直接返回该表达式的结果。如果主体是一个代码块,它将按照常规的Java语法执行,并且您可能需要使用return语句来返回值。   如果表达式只有一句代码,则可以考虑省略{} 或return 关键字。

1.3 Lambda表达式的使用

  1. 无参数的Lambda表达式:
() -> System.out.println("Hello, Lambda!");

     2. 有参数的Lambda表达式: 

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

        这里 x、y是什么参数类型,要视上层调用方法体而定。

     3. 带有多行代码的Lambda表达式:

(x, y) -> {int sum = x + y;System.out.println("Sum: " + sum);return sum;
}

     4. 函数式接口的实现

# 定义函数式接口 , 无返回值
public interface Interface1 {void getData(String mallId);}# Lambda 表达式的实现
# 如果接口只有一个参数, 则参数的 () 可以省略
# 如果表达式只有一句代码,则表达式的 {} 可以省略
Interface1 interface1  = x ->  System.out.println("线程执行");# 定义函数式接口 , 有返回值
public interface Interface2 {String getData(String mallId);}# Lambda 表达式的实现
# 只有一个参数, 则参数的 () 可以省略
# 表达式只有一句代码,则表达式的 {} 、return 都可以省略
Interface2 b = x ->  "hello";

二、Stream 流式调用 

1.1 流式调用的理解

        Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。

Stream可以由数组或集合创建,对流的操作分为两种:

中间操作:

        指每次返回一个新的流,可以有多个。这些操作是延迟执行的(lazy),也就是说它们不会立即执行,只是在遇到终端操作时才会开始执行。中间操作允许对流中的元素进行一系列转换、过滤等处理。

常见的中间操作有:

  • filter(Predicate<? super T> predicate): 过滤流中的元素。
  • map(Function<? super T, ? extends R> mapper): 将每个元素转换为另一种形式。
  • flatMap(Function<? super T, ? extends Stream<? extends R>> mapper): 将每个元素转换为一个流,然后将这些流扁平化为一个流。
  • distinct(): 去除流中的重复元素。
  • sorted(): 对流中的元素进行自然排序。
  • sorted(Comparator<? super T> comparator): 按指定的比较器对流中的元素进行排序。
  • peek(Consumer<? super T> action): 对流中的每个元素执行一个操作,并返回一个新的流。

例如:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class IntermediateOperationsExample {public static void main(String[] args) {List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");List<String> filteredNames = names.stream().filter(name -> name.startsWith("A")) // 中间操作.map(String::toUpperCase)             // 中间操作.collect(Collectors.toList());        // 终端操作filteredNames.forEach(System.out::println);}
}

终端操作:

每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。

常见的终端操作有:

  • collect(Collector<? super T, A, R> collector): 将流中的元素收集到一个集合、列表、映射等。
  • forEach(Consumer<? super T> action): 对流中的每个元素执行一个操作。
  • reduce(BinaryOperator<T> accumulator): 通过反复结合流中的元素来减少流中的元素。
  • count(): 返回流中的元素个数。
  • anyMatch(Predicate<? super T> predicate): 判断是否有任意一个元素匹配给定的谓词。
  • allMatch(Predicate<? super T> predicate): 判断是否所有元素都匹配给定的谓词。
  • noneMatch(Predicate<? super T> predicate): 判断是否没有元素匹配给定的谓词。
  • findFirst(): 返回流中的第一个元素。
  • findAny(): 返回流中的任意一个元素。

另外,Stream有几个特性:

  • stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。

  • stream不会改变数据源,通常情况下会产生一个新的集合或一个值。

  • stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

  • Stream中的元素是以Optional类型存在的。

1.2 流式调用案例

1.2.1 流的创建

// 方式一:通过 java.util.Collection.stream() 方法用集合创建流
List<String> list = Arrays.asList("a", "b", "c");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> parallelStream = list.parallelStream();// 方式二:使用java.util.Arrays.stream(T[] array)方法用数组创建流
nt[] array={1,3,5,6,8};
IntStream stream = Arrays.stream(array);// 方式三:使用Stream的静态方法:of()、iterate()、generate()
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

1.2.2 循环遍历

List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);// 遍历输出符合条件的元素
list.stream().filter(x -> x > 6).forEach(System.out::println);
// 匹配第一个
Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
// 匹配任意(适用于并行流)
Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
// 是否包含符合特定条件的元素boolean anyMatch = list.stream().anyMatch(x -> x < 6);
System.out.println("匹配第一个值:" + findFirst.get());
System.out.println("匹配任意一个值:" + findAny.get());
System.out.println("是否存在大于6的值:" + anyMatch);

1.2.3 筛选

List<String> fiterList = personList.stream().filter(x -> x.getSalary() > 8000).map(Person::getName).collect(Collectors.toList());

1.2.4 聚合

// 获取String集合中最长的元素。
Optional<String> max = list.stream().max(Comparator.comparing(String::length));
System.out.println("最长的字符串:" + max.get());// 获取Integer集合中的最大值。// 自然排序
Optional<Integer> max = list.stream().max(Integer::compareTo);
// 自定义排序
Optional<Integer> max2 = list.stream().max(new Comparator<Integer>() {@Override
public int compare(Integer o1, Integer o2) {return o1.compareTo(o2);}
});// 获取员工工资最高的人Optional<Person> max = personList.stream().max(Comparator.comparingInt(Person::getSalary));System.out.println("员工工资最大值:" + max.get().getSalary());// 计算Integer集合中大于6的元素的个数。
long count = list.stream().filter(x -> x > 6).count();
System.out.println("list中大于6的元素个数:" + count);

1.2.5 映射

映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:

  • map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

// 英文字符串数组的元素全部改为大写。
String[] strArr = { "abcd", "bcdd", "defde", "fTr" };List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());// 整数数组每个元素+3。
List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());// 将两个字符数组合并成一个新的字符数组。
List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");List<String> listNew = list.stream().flatMap(s -> {
// 将每个元素转换成一个streamString[] split = s.split(",");Stream<String> s2 = Arrays.stream(split);
return s2;}).collect(Collectors.toList());

1.2.6 规约

      归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
// 求和方式1
Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
// 求和方式2
Optional<Integer> sum2 = list.stream().reduce(Integer::sum);
// 求和方式3
Integer sum3 = list.stream().reduce(0, Integer::sum);// 求乘积
Optional<Integer> product = list.stream().reduce((x, y) -> x * y);// 求最大值方式1
Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
// 求最大值写法2
Integer max2 = list.stream().reduce(1, Integer::max);System.out.println("list求和:" + sum.get() + "," + sum2.get() + "," + sum3);
System.out.println("list求积:" + product.get());
System.out.println("list求和:" + max.get() + "," + max2);

1.2.6 收集 

// List 转 MapMap<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000).collect(Collectors.toMap(Person::getName, p -> p));// Map 转 List
map.entrySet().stream().map(a->a.getKey()).collect(Collectors.toList());

1.2.7 接合

List<String> list = Arrays.asList("A", "B", "C");String string = list.stream().collect(Collectors.joining("-"));System.out.println("拼接后的字符串:" + string);

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

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

相关文章

Pytorch训练LeNet模型MNIST数据集

如何用torch框架训练深度学习模型&#xff08;详解&#xff09; 0. 需要的包 import torch from torch.nn import CrossEntropyLoss from torch.optim import SGD from torch.utils.data import DataLoader from torchvision import datasets, transforms1. 数据加载和导入 …

Python图形界面(GUI)Tkinter笔记(九):用【Button()】功能按钮实现人机交互

在Tkinter库中,功能按钮(Button)是实现人机交互的一个非常重要的组件: 【一】主要可实现功能及意义: (1)响应用户交互: Button组件允许用户通过点击来触发某个事件或动作。当用户点击按钮时,可以执行一个指定的函数或方法。 (2)提供用户输入: Button组件是图形用户界面(G…

持续总结中!2024年面试必问 20 道 Rocket MQ面试题(三)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 20 道 Rocket MQ面试题&#xff08;二&#xff09;-CSDN博客 五、什么是生产者&#xff08;Producer&#xff09;和消费者&#xff08;Consumer&#xff09;在RocketMQ中&#xff1f; RocketMQ是一个高性能、高吞…

Linux完整版命令大全(二十五)

pine 功能说明&#xff1a;收发电子邮件&#xff0c;浏览新闻组。语  法&#xff1a;pine [-ahikorz][-attach<附件>][-attach_and_delete<附件>][-attachlist<附件清单>][-c<邮件编号>][-conf][-create_lu<地址薄><排序法>][-f<收件…

剧本杀小程序开发,探索市场发展新的商业机遇

剧本杀游戏作为一个新兴行业&#xff0c;经历了爆发式的增长&#xff0c;剧本杀游戏在市场中的热度不断升高。 不过&#xff0c;在市场的火热下&#xff0c;竞争也在逐渐加大。因此&#xff0c;在市场竞争下&#xff0c;成本低、主题多样、有趣的线上剧本杀小程序成为了创业者…

竹云董事长在第二届ICT技术发展与企业数字化转型高峰论坛作主题演讲

5月25日&#xff0c;由中国服务贸易协会指导&#xff0c;中国服务贸易协会信息技术服务委员会主办的 “第二届ICT技术发展与企业数字化转型高峰论坛” 在北京隆重召开。 本次论坛以 “数据驱动&#xff0c;AI引领&#xff0c;打造新质生产力” 为主题&#xff0c;特邀业内200余…

WebGL实现医学教学软件

使用WebGL实现医学教学软件是一个复杂但非常有益的项目&#xff0c;可以显著提升医学教育的互动性和效果。以下是详细的实现步骤&#xff0c;包括需求分析、技术选型、开发流程和注意事项。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作…

redis-cli help使用

1. redis-cli命令使用—先连接上服务器 连接到 Redis 服务器&#xff1a; 使用 redis-cli 命令即可连接到本地运行的 Redis 服务器&#xff0c;默认连接到本地的 6379 端口。 redis-cli如果 Redis 服务器不在本地或者端口不同&#xff0c;可以使用 -h 和 -p 参数指定主机和端…

华为校招机试 - LRU模拟(20240515)

题目描述 LRU(Least Recently Used)缓存算法是一种常用于管理缓存的策略,其目标是保留最近使用过的数据,而淘汰最久未被使用的数据。 实现简单的LRU缓存算法,支持查询、插入、删除操作。 最久未被使用定义:查询、插入和删除操作均为一次访问操作,每个元素均有一个最后…

探索Django 5: 从零开始,打造你的第一个Web应用

今天我们将一起探索 Django 5&#xff0c;一个备受开发者喜爱的 Python Web 框架。我们会了解 Django 5 的简介&#xff0c;新特性&#xff0c;如何安装 Django&#xff0c;以及用 Django 编写一个简单的 “Hello, World” 网站。最后&#xff0c;我会推荐一本与 Django 5 相关…

苏洵,大器晚成的家风塑造者

&#x1f4a1; 如果想阅读最新的文章&#xff0c;或者有技术问题需要交流和沟通&#xff0c;可搜索并关注微信公众号“希望睿智”。 苏洵&#xff0c;字明允&#xff0c;号老泉&#xff0c;生于宋真宗大中祥符二年&#xff08;公元1009年&#xff09;&#xff0c;卒于宋英宗治平…

量产导入 | 产品可靠性测试标准完整大集合(JEDEC/IEC/SAE…)

产品可靠性测试标准完整大集合(JEDEC/IEC/SAE…) 产品可靠性测试是产品质量保证中的重要一环, 包含有Pre-con, aging(寿命)和ESD(静电)等, 下面就收集了权威标准JEDEC全系列, 请参照如下 同时也附上其它的可靠性标准供大家参考及交叉理解, 可能侧重点不同, 大家可以参…

go语言同一包中的同一变量实现不同平台设置不同的默认值 //go:build 编译语法使用示例

在使用go来开发跨平台应用的时候&#xff0c;比如配置文件的路径&#xff0c;我们希望设置一个默认值&#xff0c;windows下的路径是类似 d:\myapp\app.conf 这样的&#xff0c; unix系统中的路径是 /opt/myapp/app.conf 这样的&#xff0c; 而我们在使用的时候需要使用的是同…

PPT忘记保存?教你如何轻松恢复

在日常办公中PPT文件作为主流文档格式&#xff0c;承载着我们大量的工作成果。然而当不小心误点了“不保存”按钮&#xff0c;或是遭遇软件崩溃等意外情况导致文档丢失时&#xff0c;文件内容是否还能够能恢复&#xff0c;往往成为我们最关心的问题。本文将为您提供五大免费且实…

NetCore PetaPoco 事务处理分享

PetaPoco是一个轻量级的.NET和Mono数据库访问库&#xff0c;它以单个C#文件的形式存在&#xff0c;便于集成到任何项目中。PetaPoco的主要特点包括无依赖性、快速的性能和对简单事务的支持。它适用于严格的没有装饰的Poco类以及几乎全部加了特性的Poco类&#xff0c;并提供了多…

现在版本的ultralytics没有setup.py以后,本地代码中修改了ultralytics源码,怎么安装到python环境中。

问题&#xff0c;在使用ultralytics训练yolov8-obb模型时&#xff0c;修改了ultralytics源码的网络结构&#xff0c;发现调用的还是pip install安装的ultralytics库&#xff0c;新版本源码中还没有setup.py&#xff0c;该怎么把源码中的ultralytics安装到环境中。 解决方法&am…

《探索网络七层模型:构建高效通信架构的关键》

在当今数字化时代&#xff0c;网络通信已经成为人们生活和工作中不可或缺的一部分。而网络七层模型作为计算机网络体系结构的重要基础&#xff0c;其技术架构对于构建高效、稳定的通信系统具有重要意义。本文将深入探讨网络七层模型的技术架构设计&#xff0c;以及其在构建现代…

轻松掌握图片批量处理,赶紧学习这些小技巧!

在现今数字化的社会中&#xff0c;我们每天都会接触到大量的图片&#xff0c;无论是在工作中还是日常生活中。要想高效处理这些图片&#xff0c;掌握图片批量处理的技巧就显得尤为重要。幸运的是&#xff0c;有许多小技巧和工具可以让这一过程变得轻松愉快。 在本文中&#xf…

长安链使用Golang编写智能合约教程(三)

本篇主要介绍长安链Go SDK写智能合约的一些常见方法的使用方法或介绍 资料来源&#xff1a; 官方文档官方示例合约库官方SDK接口文档 一、获取参数、获取状态、获取历史记录的方法解析 注意&#xff01; 这些查询链上数据的方法&#xff1a;只能是查询本合约之前上链的数据&a…

信息学一周赛事安排

本周比赛提醒 本周有以下几场比赛即将开始&#xff1a; 1.ABC-356 比赛时间&#xff1a;6月1日&#xff08;周六&#xff09;晚20:00 比赛链接&#xff1a;https://atcoder.jp/contests/abc356 2.ARC-179 比赛时间&#xff1a;6月2日&#xff08;周日&#xff09;晚20:00 …