Java函数式编程【二】【Stream的装饰】【中间操作】【map映射器】【摊平映射器flatMap】
一、Java的Stream流式编程中的中间操作
Java的Stream流式编程中,中间操作是对数据流进行处理的一种方式,这些操作通常返回流对象本身,以便可以链接更多的操作。以下是一些常见的中间操作:
-
filter(Predicate predicate) - 用于通过设定的条件过滤出元素。
-
sorted() - 对元素进行排序。
-
distinct() - 去除重复的元素。
-
limit(long maxSize) - 获取指定数量的流元素。
-
skip(long n) - 跳过操作,跳过某些元素。
-
peek() - 查看操作。允许你在不影响流的主要处理逻辑的情况下,查看或使用流中的每个元素。这个方法可以用来进行一些调试或日志记录等操作。下面是一个示例:
peek例程
List<String> fruits = Arrays.asList("apple", "banana", "orange", "grape");
fruits.stream().filter(f -> f.length() > 5).peek(System.out::println).collect(Collectors.toList());
中间操作的示例代码:
List<String> items = Arrays.asList("apple", "banana", "orange", "kiwi");// Filtering
List<String> filteredItems = items.stream().filter(item -> item.startsWith("a")).collect(Collectors.toList());// Sorting
List<String> sortedItems = items.stream().sorted().collect(Collectors.toList());// Distinct
List<String> distinctItems = items.stream().distinct().collect(Collectors.toList());// Limiting
List<String> limitedItems = items.stream().limit(2).collect(Collectors.toList());// Skipping
List<String> skippedItems = items.stream().skip(1).collect(Collectors.toList());
函数式编程,在流管道中可以包含0个或n个中间操作,每个中间操作都返回一个新的流。
二、中间操作 映射器map()的用法
映射器map的方法签名(原型):
- map(Function<? super T, ? extends R> mapper) - 它的输入参数是一个类型为函数接口的映射器,可将流中的元素转换成其他类型的元素。映射器map()是把一个对象流变成另一种对象流。
另外三个与映射器map()类似的映射器,它们则可以把一个对象流转换为基本类型流。
- mapToInt(ToIntFunction<? super T> mapper) - 将元素映射为值的整型int流。
- mapToLong(ToLongFunction<? super T> mapper) - 将元素映射为值的长整型long流。
- mapToDouble(ToDoubleFunction<? super T> mapper) - 将元素映射为值的双精度浮点型double流。
用法一:将一种流映射成另一种流
把英文的小写转换为大写的代码片断:
// Mapping
List<String> items = Arrays.asList("apple", "banana", "orange", "grape");
List<String> mappedItems = items.stream().map(String::toUpperCase).collect(Collectors.toList());
下面是来看一个完整的示例。下图是这个流管道的详细分解说明图示:
这个示例完整的程序源码:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class MapTest {public static void main(String[] args) {List<User> list = Arrays.asList(new User(2001, "Ricky"), new User(2002, "Alex"), new User(2003, "Bob"));list.forEach(System.out::println);List<String> newList = list.stream().map(User::getName).sorted().limit(2).collect(Collectors.toList());newList.forEach(System.out::println);}
}class User {private int id;private String name;public User(int id,String name) {this.id = id;this.name = name;}public String getName() {return name;}@Overridepublic String toString() {return "{User[ID:"+id+" 姓名:"+name+"]}";}
}
例程测试效果图:
映射器map示例: 实现功能:整数列表每个元素+3。分别用对象流和IntStream来实现。
使用的两个映射器的原型如下所示:
//本示例使用的map()方法的签名,其入口参数类型是Function函数,如下:
<Integer> Stream<Integer> java.util.stream.Stream.map(Function<? super Integer, ? extends Integer> mapper)
//本示例使用的mapToInt()方法的签名,其入口参数类型是ToIntFunction函数,如下
IntStream java.util.stream.Stream.mapToInt(ToIntFunction<? super Integer> mapper)
这两个流,尽管入口参数的函数类型不一样,但完全可以用同一个Lambda表达式来代替函数接口的实例作为传入参数。
但后续的处理方式有些不同:映射器map()返回的是对象流,可用收集器collect(Collectors.toList())来收集结果。映射器mapToInt()返回的是IntStream(整型流),不能使用用收集器。因为收集器收集的元素必须是对象,IntStream中的元素是基本数据类型,所以收集器不支持。
List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);//对象流的实现方式List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());System.out.println("每个元素+3:" + intListNew);//用IntStream来实现System.out.println("打印IntStream:");IntStream intStream = intList.stream().mapToInt(x -> x + 3);intStream.forEach(System.out::println);
测试效果图:
mapToDouble基本数据类型流例程
基本数据类型流,比如DoubleStream(双精度浮点型流)不能使用收集器收集结果,但也有很多的终止操作,比如求最大最小值、求和、求平均值:
public static void main(String[] args) {List<Double> doubleList = Arrays.asList(1.0, 22.0, 3.0, 4.0, 32.0);double average = doubleList.stream().mapToDouble(Number::doubleValue).average().getAsDouble();double sum = doubleList.stream().mapToDouble(Number::doubleValue).sum();double max = doubleList.stream().mapToDouble(Number::doubleValue).max().getAsDouble();System.out.println("平均值:" + average + ",总和:" + sum + ",最大值:" + max);
}
测试结果: 平均值:12.4,总和:62.0,最大值:32.0
三、中间操作 摊平映射器flatMap()的用法
- flatMap(Function<? super T, ? extends Stream<? extends R>> mapper) - 将每个元素转换为某种元素类型的流,然后将它们连接成一个流。
摊平映射器flatMap()示例一:
public class StreamTest {public static void main(String[] args) {List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");List<String> listNew = list.stream().flatMap(s -> {// 将每个元素转换成一个streamString[] split = s.split(",");return Arrays.stream(split);}).collect(Collectors.toList());System.out.println("处理前的集合:" + list);System.out.println("处理后的集合:" + listNew);}
}
在这个例子中,初始时对象流的元素类型是长度为7的字符串:“m,k,l,a"和"1,3,5,7”。[ “m,k,l,a” , “1,3,5,7” ]。通过摊平映射器flatMap()转换后的对象流的元素类型是长度为1的字符串。最终对象流为[ “m” , “k” , “l” , “a” , “1” , “3” , “5” , “7” ]
实际上,上面的示例程序还可以简化,可简化为:
List<String> listNew = list.stream().flatMap(str->Stream.of(str.split(","))).collect(Collectors.toList());
摊平映射器flatMap()示例二:
package stream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class FlatMapTest {public static void test1() {List<String> items = Arrays.asList("glass", "brick","gold", "silver");List<String> flatMappedItems = items.stream().flatMap(item -> Stream.of(item.split(""))).collect(Collectors.toList());flatMappedItems.forEach(System.out::println);}public static void test2() {String songs = "Remember me to one who lives there";String[] words = songs.split(" ");List<String> strList = Arrays.stream(words).map(s -> s.split("e")).flatMap(e -> Arrays.stream(e)).collect(Collectors.toList());strList.forEach(System.out::println);}public static void main(String[] args) {test1();test2();}
}
测试结果图:
流的连接:有两种方式。如果是两个流的连接,可使用 Stream.concat() 方法;
如果是三个及三个以上流的连接,就使用 摊平映射器flatMap() 方法。
摊平映射器flatMap还可以用来实现流的连接,请看例程:
public static void concatStream() {String names[][] = { {"Alice", "Alien", "Bob"},{"Jack", "John", "Jobs"},{"Maria", "Golf", "Korea"} };//两个流的连接Stream<String> concat = Stream.concat(Arrays.stream(names[0]), Arrays.stream(names[1]));concat.forEach(System.out::println);System.out.println("===========");//多个流的连接,例子之一List<String[]> list = Arrays.asList(names);Stream<String> strStream = list.stream().flatMap(e->Arrays.stream(e));strStream.forEach(System.out::println);System.out.println("===========");Stream<String> first = Stream.of("Alice", "Alien", "Bob");Stream<String> second = Stream.of("Jack", "John", "Jobs");Stream<String> third = Stream.of("Maria", "Golf", "Korea");//多个流的连接,例子之二//Stream<String> stringStream = Stream.of(first, second, third).flatMap(s->s);Stream<String> stringStream = Stream.of(first, second, third).flatMap(Function.identity());stringStream.forEach(System.out::println);}
说明: 多个流的连接,“例子之一”和“例子之二”实现相同功能。另外,示例中“flatMap(Function.identity())”等价于“flatMap(s->s)”。
摊平映射器有很多,例如摊平为基本数据类型流的映射器(可由类型T的对象流转换为基本数据类型的流):
- IntStream flatMapToInt(Function<? super T, ? extends IntStream> mapper);
- LongStream flatMapToLong(Function<? super T, ? extends LongStream> mapper);
- DoubleStream flatMapToDouble(Function<? super T, ? extends DoubleStream> mapper);
映射器map和flatMap的区别
map()操作将每个元素转换成一个新元素,并将所有这些新生成的元素收集到一个新的流中。
flatMap()操作将每个元素转换成一个新的流,并将所有这些新生成的流合并成一个单一的流。
flatMap()和map()之间还有一个重要的区别,那就是flatMap()支持处理包含嵌套数据结构的流。
参考文献:
- Java8 Stream:2万字20个实例,玩转集合的筛选、归约、分组、聚合-CSDN
- 恕我直言你可能真的不会java系列-CSDN
- Java8 Stream流使用-CSDN
- Java 8 Stream API:从基础到高级,掌握流处理的艺术
- JAVA8专题-Stream流操作详解
- Java 8新特性Stream()流
- Java8 特性笔记(四) Stream
第1篇:lambda表达式会用了么?
第2篇:Java Stream API?
第3篇:Stream的Filter与谓词逻辑
第4篇:Stream管道流Map操作
第5篇:Stream的状态与并行操作
第7篇:像使用SQL一样排序集合
第8篇-函数式接口
第9篇-元素的匹配与查找
第10篇-集合元素归约
第11篇-Stream API终端操作
Java Stream函数式编程第三篇:管道流结果处理
相关文章:
Java函数式编程【二】【Stream的装饰】【中间操作】【map映射器】【摊平映射器flatMap】
一、Java的Stream流式编程中的中间操作 Java的Stream流式编程中,中间操作是对数据流进行处理的一种方式,这些操作通常返回流对象本身,以便可以链接更多的操作。以下是一些常见的中间操作: filter(Predicate predicate) - 用于通过…...
树莓派明明安装了opencv和numpy,却找不到
当然不止树莓派,配置python环境都可能存在这个问题 可能是因为安装的 numpy 或者 opencv 版本与 Python 的包路径不匹配。下面是问题的常见原因及解决方法:【方法一和二优先考虑】 原因分析 多版本 Python 环境冲突: 树莓派上可能有多个版本…...
numpy.float8不存在;Python中,实现16位浮点数
目录 python中矩阵的浮点数存储 numpy.float8不存在 Python中,实现16位浮点数 实现 float16 关于 float8 python中矩阵的浮点数存储 在Python中,矩阵通常是通过嵌套列表(list of lists)、NumPy数组(numpy.ndarray)或其他类似的数据结构来表示的。矩阵中存储的数值所…...
Redis集群配置 (不使用docker 部署)
1. Redis集群简介 1.1 什么是Redis集群 Redis集群是一种通过将多个Redis节点连接在一起以实现高可用性、数据分片和负载均衡的技术。它允许Redis在不同节点上同时提供服务,提高整体性能和可靠性。根据搭建的方式和集群的特性,Redis集群主要有三种模式&…...
HTML5系列(7)-- Web Storage 实战指南
前端技术探索系列:HTML5 Web Storage 实战指南 🗄️ 致读者:本地存储的新纪元 👋 前端开发者们, 今天我们将深入探讨 HTML5 中的 Web Storage 技术,这是一个强大的本地存储解决方案,让我们能…...
【在Linux世界中追寻伟大的One Piece】读者写者问题与读写锁
目录 1 -> 读者写者问题 1.1 -> 什么是读者写者问题 1.2 -> 读者写者与生产消费者的区别 1.3 -> 如何理解读者写者问题 2 -> 读写锁 2.1 -> 读写锁接口 3 -> 读者优先(Reader-Preference) 4 -> 写者优先(Writer-Preference) 1 -> 读者写者…...
用到动态库的程序运行过程
当我们写好了一段代码然后编译运行后会生成可执行文件,该文件会存在磁盘的当前目录下,而当我们开始运行这段程序时,操作系统(加载器)需要将其从磁盘加载进内存然后执行相关操作,而对于用到动态库的程序&…...
类型转换与IO流:C++世界的变形与交互之道
文章目录 前言🎄一、类型转换🎈1.1 隐式类型转换🎈1.2 显式类型转换🎁1. C 风格强制类型转换🎁2. C 类型转换操作符 🎈1.3 C 类型转换操作符详解🎁1. static_cast🎁2. dynamic_cast&…...
Pytorch使用手册- TorchVision目标检测微调Tutorial的使用指南(专题十二)
这篇教程的目标是对一个预训练的 Mask R-CNN 模型进行微调,应用于 Penn-Fudan 行人检测与分割数据集。该数据集包含 170 张图像,里面有 345 个行人实例,我们将通过这个教程来演示如何使用 torchvision 中的新特性,训练一个面向自定义数据集的目标检测和实例分割模型。 注意…...
人工智能机器学习算法分类全解析
目录 一、引言 二、机器学习算法分类概述 (一)基于学习方式的分类 1. 监督学习(Supervised Learning) 2. 无监督学习(Unsupervised Learning) 3. 强化学习(Reinforcement Learning…...
Linux 35.6 + JetPack v5.1.4@DeepStream安装
Linux 35.6 JetPack v5.1.4DeepStream安装 1. 源由2. 步骤Step 1 安装Jetpack 5.1.4 L4T 35.6Step 2 安装依赖组件Step 3 安装librdkafkaStep 4 安装 DeepStream SDKStep 5 测试 deepstream-appStep 6 运行 deepstream-app 3. 总结3.1 版本问题3.2 二进制help 4. 参考资料 1. …...
图数据库 | 11、图数据库架构设计——高性能图存储架构(下)
在上篇内容中,老夫着重讲了高性能图存储系统的特点,咱们继续往下讲重点——高性能存储架构的设计思路!! 2.高性能存储架构设计思路 首先呢,存储架构以及核心数据结构的设计思路通常围绕如下4个维度来进行:…...
【HTTP】HTTP协议
一个Web Server就是个服务器软件(程序),或者是运行这个服务器软件的硬件(计算机),其主要功能是通过HTTP协议与客户端进行通信,来接收,存储,处理来自客户端的HTTP请求&…...
大数据新视界 -- Hive 基于 MapReduce 的执行原理(上)(23 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
SpringBoot源码解析(六):打印Banner
SpringBoot源码系列文章 SpringBoot源码解析(一):SpringApplication构造方法 SpringBoot源码解析(二):引导上下文DefaultBootstrapContext SpringBoot源码解析(三):启动开始阶段 SpringBoot源码解析(四):解析应用参数args Sp…...
【计算机网络】实验6:IPV4地址的构造超网及IP数据报
实验 6:IPV4地址的构造超网及IP数据报 一、 实验目的 加深对IPV4地址的构造超网(无分类编制)的了解。 加深对IP数据包的发送和转发流程的了解。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、了解IPV4地址的构造超网…...
easy excel 生成excel 文件
导包 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.3</version> </dependency> 内容 List<类> limspjreport 值; String fileName sdf.format(new Date()) "-…...
Ajax:回忆与节点
一点回忆 面对我的Ajax学习,实现前后端交互,最开始我采用的使用网络寻找intellij IDEA Ultimate破解方法,然后最终成功,然后按照相关教程配置java ee项目,然后中间又去配置了Tomcat服务器,然后又去学习了一…...
Python+OpenCV系列:Python和OpenCV的结合和发展
PythonOpenCV系列:Python和OpenCV的结合和发展 **引言****Python语言的发展****1.1 Python的诞生与发展****1.2 Python的核心特性与优势****1.3 Python的应用领域** **OpenCV的发展****2.1 OpenCV的起源与发展****2.2 OpenCV的功能特性****2.3 OpenCV的应用场景** *…...
Ubuntu20.04 由源码编译安装opencv3.2 OpenCV
Ubuntu20.04 由源码编译安装opencv3.2.0 获取 opencv 及opencv_contrib源代码 创建目录以存放opencv及opencv_contrib源代码 mkdir ~/opencv3.2.0 cd ~/opencv3.2.0获取opencv源代码并切换到对应tag git clone https://github.com/opencv/opencv.git cd opencv git checkou…...
A058-基于Spring Boot的餐饮管理系统的设计与实现
🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看项目链接获取⬇️,记得注明来意哦~🌹 赠送计算机毕业设计600个选题ex…...
RDIFramework.NET CS敏捷开发框架 SOA服务三种访问(直连、WCF、WebAPI)方式
1、介绍 在软件开发领域,尤其是企业级应用开发中,灵活性、开放性、可扩展性往往是项目成功的关键因素。对于C/S项目,如何高效地与后端数据库进行交互,以及如何提供多样化的服务访问方式,是开发者需要深入考虑的问题。…...
Linux——命名管道及日志
linux——进程间通信及管道的应用场景-CSDN博客 文章目录 目录 文章目录 前言 一、命名管道是什么? 理解: 2、编写代码 makefile 管道封装成类,想用中管道时只需要调用实例化 读端 写端 日志 1、日志是什么? 2、日志有什么&#x…...
Flink 常见面试题
1、Flink 的四大特征(基石) checkpoin基于Chandy-Lamport算法实现了分布式一致性快照提供了一致性的语义 state丰富的StateAPI time实现了Watermark机制,乱序数据处理,迟到数据容忍 window开箱即用的滚动,滑动会话窗口…...
rtc-pcf8563 0-0051: low voltage detected, date/time is not reliable
解决方法: 1、先测量pcf8563电源电压,是否满足要求。 2、pcf8563首次操作。第一次读取pcf8563的时间,未初始化,非法,芯片门槛电压检测配置不合理。使用hwclock命令写入一次,即可解决。 hwclock -f /dev/…...
(简单5步实现)部署本地AI大语言模型聊天系统:Chatbox AI + grok2.0大模型
摘要: 本文将指导您如何部署一个本地AI大语言模型聊天系统,使用Chatbox AI客户端应用和grok-beta大模型,以实现高效、智能的聊天体验。 引言: 由马斯克X-AI发布的Grok 2大模型以其卓越的性能超越了GPT4.0。Grok模型支持超长文本…...
MAUI APP开发蓝牙协议的经验分享:与跳绳设备对接
在开发MAUI应用程序时,蓝牙协议的应用是一个重要的环节,尤其是在需要与外部设备如智能跳绳进行数据交换的场景中。以下是我在开发过程中的一些经验和心得,希望能为你的项目提供帮助。 1. 蓝牙协议基础 蓝牙协议是无线通信的一种标准&#x…...
最新版Node.js下载安装及环境配置教程
目录 初识:Node.js 一、下载:Node.js 二、安装:Node.js 1.下载【node.js】压缩包安装文件 2.解压下载的安装包 3.打开解压的【node-v22.11.0-x64】文件夹 4.双击启动安装程序 5.点击【Next】 6.勾选【I accept the terms in the Lic…...
51c自动驾驶~合集39
我自己的原文哦~ https://blog.51cto.com/whaosoft/12707676 #DiffusionDrive 大幅超越所有SOTA!地平线DiffusionDrive:生成式方案或将重塑端到端格局? 近年来,由于感知模型的性能持续进步,端到端自动驾驶受到了来…...
单链表基础操作
文章目录 abstract定义结点结构初始化链表遍历链表求表长查找结点根据序号查找结点根据值查找结点 插入结点首尾位置插入一般位置插入(通用插入)找到尾元素|尾指针相关操作 删除结点 abstract 单链表是一种简单的动态数据结构,它由一系列结点组成,每个结…...
炉石卡牌制作网页/seo自动点击排名
在PHP语言总,单引号与双引号的作用不尽相同。 PHP单引号及双引号均可以修饰字符串类型的数据,如果修饰的字符串中含有变量(例$name);最大的区别是:双引号会替换变量的值,而单引号会把它当做字符…...
网站开发算前端吗/平板电视seo优化关键词
汽车租赁企业,一直用自己的方式,谋求发展,立足长远,不断改进,现在又推出了新的政策,对于汽车的年龄超过6年之上的车辆,不易出租,并且公布了相关的规范,目前整理了几个关于…...
中国联通网站备案系统/接广告的平台推荐
题目 小明 PAT 考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔 N 个人就发出一个红包。请你编写程序帮助他确定中奖名单。 输入格式: 输入第一行给出三个正整数 M(≤ 1000)、N 和 Sÿ…...
网站怎么做可以被收录/电脑办公软件培训班
Orientations: SupportedOrientations支持的手机朝向,Orientation当前朝向 手机朝向控制拥有Portrait(正直),Landscape(平放),PortraitOrLandscape(正直or平放)三种 XNA的设置方法: graphics.SupportedOrientations DisplayOrientation.Portrait | DisplayOrientation.Landsca…...
网站开发框架的主要作用/微信软文是什么意思
rpm -i --test abc.rpm...
商丘做手机做网站/好项目推荐平台
GTK中的构件II(Widgets)GTK中的构件II(Widgets)在本章的GTK程序设计中,我们仍然要继续向大家介绍和展示各种各样的构件。GtkComboBoxGtkComboBox构件的作用是让程序使用者根据不同的需求从很多选项中进行选择。#include <gtk/gtk.h>void combo_selected(GtkWi…...