当前位置: 首页 > news >正文

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流式编程中&#xff0c;中间操作是对数据流进行处理的一种方式&#xff0c;这些操作通常返回流对象本身&#xff0c;以便可以链接更多的操作。以下是一些常见的中间操作&#xff1a; filter(Predicate predicate) - 用于通过…...

树莓派明明安装了opencv和numpy,却找不到

当然不止树莓派&#xff0c;配置python环境都可能存在这个问题 可能是因为安装的 numpy 或者 opencv 版本与 Python 的包路径不匹配。下面是问题的常见原因及解决方法&#xff1a;【方法一和二优先考虑】 原因分析 多版本 Python 环境冲突&#xff1a; 树莓派上可能有多个版本…...

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在不同节点上同时提供服务&#xff0c;提高整体性能和可靠性。根据搭建的方式和集群的特性&#xff0c;Redis集群主要有三种模式&…...

HTML5系列(7)-- Web Storage 实战指南

前端技术探索系列&#xff1a;HTML5 Web Storage 实战指南 &#x1f5c4;️ 致读者&#xff1a;本地存储的新纪元 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 HTML5 中的 Web Storage 技术&#xff0c;这是一个强大的本地存储解决方案&#xff0c;让我们能…...

【在Linux世界中追寻伟大的One Piece】读者写者问题与读写锁

目录 1 -> 读者写者问题 1.1 -> 什么是读者写者问题 1.2 -> 读者写者与生产消费者的区别 1.3 -> 如何理解读者写者问题 2 -> 读写锁 2.1 -> 读写锁接口 3 -> 读者优先(Reader-Preference) 4 -> 写者优先(Writer-Preference) 1 -> 读者写者…...

用到动态库的程序运行过程

当我们写好了一段代码然后编译运行后会生成可执行文件&#xff0c;该文件会存在磁盘的当前目录下&#xff0c;而当我们开始运行这段程序时&#xff0c;操作系统&#xff08;加载器&#xff09;需要将其从磁盘加载进内存然后执行相关操作&#xff0c;而对于用到动态库的程序&…...

类型转换与IO流:C++世界的变形与交互之道

文章目录 前言&#x1f384;一、类型转换&#x1f388;1.1 隐式类型转换&#x1f388;1.2 显式类型转换&#x1f381;1. C 风格强制类型转换&#x1f381;2. C 类型转换操作符 &#x1f388;1.3 C 类型转换操作符详解&#x1f381;1. static_cast&#x1f381;2. dynamic_cast&…...

Pytorch使用手册- TorchVision目标检测微调Tutorial的使用指南(专题十二)

这篇教程的目标是对一个预训练的 Mask R-CNN 模型进行微调,应用于 Penn-Fudan 行人检测与分割数据集。该数据集包含 170 张图像,里面有 345 个行人实例,我们将通过这个教程来演示如何使用 torchvision 中的新特性,训练一个面向自定义数据集的目标检测和实例分割模型。 注意…...

人工智能机器学习算法分类全解析

目录 一、引言 二、机器学习算法分类概述 &#xff08;一&#xff09;基于学习方式的分类 1. 监督学习&#xff08;Supervised Learning&#xff09; 2. 无监督学习&#xff08;Unsupervised Learning&#xff09; 3. 强化学习&#xff08;Reinforcement Learning&#xf…...

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、图数据库架构设计——高性能图存储架构(下)

在上篇内容中&#xff0c;老夫着重讲了高性能图存储系统的特点&#xff0c;咱们继续往下讲重点——高性能存储架构的设计思路&#xff01;&#xff01; 2.高性能存储架构设计思路 首先呢&#xff0c;存储架构以及核心数据结构的设计思路通常围绕如下4个维度来进行&#xff1a…...

【HTTP】HTTP协议

一个Web Server就是个服务器软件&#xff08;程序&#xff09;&#xff0c;或者是运行这个服务器软件的硬件&#xff08;计算机&#xff09;&#xff0c;其主要功能是通过HTTP协议与客户端进行通信&#xff0c;来接收&#xff0c;存储&#xff0c;处理来自客户端的HTTP请求&…...

大数据新视界 -- Hive 基于 MapReduce 的执行原理(上)(23 / 30)

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

SpringBoot源码解析(六):打印Banner

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args Sp…...

【计算机网络】实验6:IPV4地址的构造超网及IP数据报

实验 6&#xff1a;IPV4地址的构造超网及IP数据报 一、 实验目的 加深对IPV4地址的构造超网&#xff08;无分类编制&#xff09;的了解。 加深对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学习&#xff0c;实现前后端交互&#xff0c;最开始我采用的使用网络寻找intellij IDEA Ultimate破解方法&#xff0c;然后最终成功&#xff0c;然后按照相关教程配置java ee项目&#xff0c;然后中间又去配置了Tomcat服务器&#xff0c;然后又去学习了一…...

Python+OpenCV系列:Python和OpenCV的结合和发展

PythonOpenCV系列&#xff1a;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…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...