每天学一点之Stream流相关操作
StreamAPI
一、Stream特点
Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,负责存储数据,Stream流讲的是计算,负责处理数据!”
注意:
①Stream 自己不会存储元素。
②Stream 不会改变源对象。每次处理都会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。
二、Stream操作的步骤
1- 创建 Stream:通过一个数据源(如:集合、数组),获取一个流
2- 中间操作:每次处理都会返回一个持有结果的新Stream,即中间操作的方法返回值仍然是Stream类型的对象,因此中间操作可以是个操作链(返回值类型是Stream类型的可以一直使用.方法
操作),可对数据源的数据进行n次处理,但是在终结操作前,并不会真正执行。
3- 终止操作:终止操作的方法返回值类型就不再是Stream了,因此一旦执行终止操作,就结束整个Stream操作了。一旦执行终止操作,就执行中间操作链,最终产生结果并结束Stream。
案例分析:
@Testpublic void test1(){//1、创建Stream,指定数据源来创建StreamArrayList<String> list = new ArrayList<>();list.add("hello");list.add("java");list.add("hi");list.add("heihei");Stream<String> stream = list.stream();//2、加工处理//假设我要处理的要求:把里面所有的e字母,修改为a//Function<T,R> 的抽象方法 R apply(T t)stream = stream.map(s-> s.replace('e','a'));//假设我要处理的要求:筛选出包含a字母的单词//Predicate<T>接口 boolean test(T t)stream = stream.filter(s -> s.contains("a"));//处理,打印所有包含"a"字母的单词//Consumer<T> 的抽象方法 void accept(T t)stream = stream.peek( s -> System.out.println(s));//3、结束处理//统计满足条件的单词的个数
// long count = stream.count();//没有这一步,前面的加工处理不执行
// System.out.println("count = " + count);System.out.println("list = " + list);//不会修改数据源}
没有开启3、结束处理步骤时的运行结果:
开启之后的运行结果:
三、创建StreamAPI
1、创建 Stream方式一:通过集合
Java8 中的 Collection 接口被扩展,提供了两个获取流的方法:
-
public default Stream stream() : 返回一个顺序流
-
public default Stream parallelStream() : 返回一个并行流
Stream stream = list.stream();
2、创建 Stream方式二:通过数组
Java8 中的 Arrays 的静态方法 stream() 可以获取数组流:
- public static Stream stream(T[] array): 返回一个流
String[] arr = {“hello”,“world”,“java”};
Stream stream = Arrays.stream(arr);
3、创建 Stream方式三:通过Stream的of()
可以调用Stream类静态方法 of(), 通过显示值创建一个流。它可以接收任意数量的参数。
- public static Stream of(T… values) : 返回一个顺序流
Stream stringStream = Stream.of(“hello”, “world”, “java”);
4、创建 Stream方式四:创建无限流
可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。
- public static Stream iterate(final T seed, final UnaryOperator f):返回一个无限流
- public static Stream generate(Supplier s) :返回一个无限流
@Testpublic void test4(){//Supplier<T> 的抽象方法 T get()Stream<Double> stream = Stream.generate(() -> Math.random());//结束Stream//Consumer<T> 的抽象方法 void accept(T t)stream.forEach(t-> System.out.println(t));}@Testpublic void test5(){//Stream<T> iterate(final T seed, final UnaryOperator<T> f)//seed:种子//UnaryOperator<T>: T apply(T t)
// Stream<Integer> stream = Stream.iterate(1, t -> t+2);Stream<Integer> stream = Stream.iterate(1, t -> {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}return t+2;});//结束Stream//Consumer<T> 的抽象方法 void accept(T t)stream.forEach(System.out::println);}
}
四、中间操作API
多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。
序号 | 方 法 | 描 述 |
---|---|---|
1 | Stream filter(Predicate p) | 接收 Lambda , 从流中排除某些元素 |
2 | Stream distinct() | 筛选,通过流所生成元素的equals() 去除重复元素 |
3 | Stream limit(long maxSize) | 截断流,使其元素不超过给定数量 |
4 | Stream skip(long n) | 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补 |
5 | Stream peek(Consumer action) | 接收Lambda,对流中的每个数据执行Lambda体操作 |
6 | Stream sorted() | 产生一个新流,其中按自然顺序排序 |
7 | Stream sorted(Comparator com) | 产生一个新流,其中按比较器顺序排序 |
8 | Stream map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。 |
9 | Stream mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。 |
10 | Stream mapToInt(ToIntFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。 |
11 | Stream mapToLong(ToLongFunction f) | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。 |
12 | Stream flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
/*需求:给你一组单词,统计里面使用了几个字母,并找出这些字母*//*<R> Stream<R> map(Function<? super T, ? extends R> mapper);T类型->R类型对象<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);T类型->Stream<R>流*/Set<String> set = Stream.of("hello", "java", "world", "xiaoyu") //把所有单词的每一个字母取出来.flatMap(s -> Arrays.stream(s.split("|"))).collect(Collectors.toSet());System.out.println("字母有:"+set);System.out.println("个数:" + set.size());/*字母有:[a, d, e, h, i, j, l, o, r, u, v, w, x, y]个数:14*/
案例:
@Testpublic void test10(){//找出最老的3个员工,年龄最大的3个员工ArrayList<Employee> list = new ArrayList<>();list.add(new Employee(1,"张三",23,15000));list.add(new Employee(2,"李四",24,14000));list.add(new Employee(3,"王五",25,18000));list.add(new Employee(4,"赵六",22,12000));list.add(new Employee(5,"陈前",29,12000));list.add(new Employee(6,"林上清",27,12000));list.add(new Employee(7,"昆昆",27,12000));//年龄第3名的员工,年龄值不能重复//思路:先找出年龄值是第3的值,然后再找员工//Stream mapToInt(ToIntFunction f)//ToIntFunction<T> int applyAsInt(T value);OptionalInt ageOption = list.stream().sorted((t1,t2)->t2.getAge()-t1.getAge()).mapToInt(emp -> emp.getAge()).distinct().skip(2).findFirst();System.out.println("age = " + ageOption);list.stream().filter(emp -> emp.getAge() == ageOption.getAsInt()).forEach(t-> System.out.println(t));}
五、终结操作API
终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void。流进行了终止操作后,不能再次使用。
序号 | 方法的返回值类型 | 方法 | 描述 |
---|---|---|---|
1 | boolean | allMatch(Predicate p) | 检查是否匹配所有元素 |
2 | boolean | anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
3 | boolean | noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
4 | Optional | findFirst() | 返回第一个元素 |
5 | Optional | findAny() | 返回当前流中的任意元素 |
6 | long | count() | 返回流中元素总数 |
7 | Optional | max(Comparator c) | 返回流中最大值 |
8 | Optional | min(Comparator c) | 返回流中最小值 |
9 | void | forEach(Consumer c) | 迭代 |
10 | T | reduce(T iden, BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 T |
11 | U | reduce(BinaryOperator b) | 可以将流中元素反复结合起来,得到一个值。返回 Optional |
12 | R | collect(Collector c) | 将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法 |
Stream<Integer> stream = Stream.of(1, 2, 3, 5, 7, 9);//判断stream中的所有数据,是否都满足 偶数的要求//allMatch(Predicate<? super T> predicate)//Predicate<T> boolean test(T t)boolean result = stream.allMatch(num -> num % 2 == 0);//判断stream中的所有数据,是否有数字满足 偶数的要求//anyMatch(Predicate<? super T> predicate)//Predicate<T> boolean test(T t)boolean result = stream.anyMatch(num -> num % 2 == 0);}//判断stream中的所有数据,是否都不满足 偶数的要求//noneMatch(Predicate<? super T> predicate)//Predicate<T> boolean test(T t)boolean result = stream.noneMatch(num -> num % 2 == 0);//获取流中第一个元素Optional<Integer> first = stream.findFirst();//加工处理一下,筛选出所有的偶数//Stream<T> filter(Predicate<? super T> predicate);//Predicate<T> boolean test(T t)stream = stream.filter(num -> num%2==0);//统计流中的元素个数long count = stream.count();//找出流中的最大值和最小值//Comparator<T> int compare(T t1 ,T t2)Optional<Integer> max = stream.max((t1, t2) -> t1-t2);Optional<Integer> min = stream.min((t1, t2) -> t1 - t2);//遍历流中的数据// void forEach(Consumer<? super T> action);//Consumer<T> 的抽象方法 void accept(T t)stream.forEach(t-> System.out.println(t));//使用reduce方法找出最大值,不用max方法//Optional<T> reduce(BinaryOperator<T> accumulator);//BinaryOperator<T,T> T apply(T t1, T t2)Optional<Integer> max = stream.reduce((t1, t2) -> t1 > t2 ? t1 : t2);//把流中的元素值累加起来//Optional<T> reduce(BinaryOperator<T> accumulator);//BinaryOperator<T,T> T apply(T t1, T t2)final Optional<Integer> sum = stream.reduce((t1, t2) -> t1 + t2);//筛选出所有的偶数,放到一个List集合中//中间处理//Stream<T> filter(Predicate<? super T> predicate);//Predicate<T> boolean test(T t)stream = stream.filter(t->t%2==0);//收集这些元素到List中List<Integer> list = stream.collect(Collectors.toList());//筛选出所有的偶数,放到一个Set集合中//中间处理//Stream<T> filter(Predicate<? super T> predicate);//Predicate<T> boolean test(T t)stream = stream.filter(t->t%2==0);Set<Integer> set = stream.collect(Collectors.toSet());
相关文章:
每天学一点之Stream流相关操作
StreamAPI 一、Stream特点 Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,负责存储数据,Stream流讲的是计算,负责处理数据!” 注意: ①Str…...
MatCap模拟光照效果实现
大家好,我是阿赵 之前介绍过各种光照模型的实现方法。那些光照模型的实现虽然有算法上的不同,但基本上都是灯光方向和法线方向的计算得出的明暗结果。 下面介绍一种叫做MatCap的模拟光照效果,这种方式计算非常简单,脱离灯光的计算…...
二十一、PG管理
一、 PG异常状态说明 1、 PG状态介绍 可以通过ceph pg stat命令查看PG当前状态,健康状态为“active clean” [rootrbd01 ~]# ceph pg stat 192 pgs: 192 activeclean; 1.3 KiB data, 64 MiB used, 114 GiB / 120 GiB avail; 85 B/s rd, 0 op/s2、pg常见状态 状…...
SAPUI5开发01_01-Installing Eclipse
1.0 简要要求概述: 本节您将安装SAPUI 5,以及如何在Eclipse Juno中集成SAPUI 5工具。 1.1 安装JDK JDK 是一种用于构建在 Java 平台上发布的应用程序、Applet 和组件的开发环境,即编写 Java 程序必须使用 JDK,它提供了编译和运行 Java 程序的环境。 在安装 JDK 之前,首…...
Qt之高仿QQ系统设置界面
QQ或360安全卫士的设置界面都是非常有特点的,所有的配置项都在一个垂直的ScrollArea中,但是又能通过左侧的导航栏点击定位。这样做的好处是既方便查看指定配置项,又方便查看所有配置项。 一.效果 下面左边是当前最新版QQ的系统设置界面,右边是我的高仿版本,几乎一毛一样…...
JVM概览:内存空间与数据存储
核心的五个部分虚拟机栈:局部变量中基础类型数据、对象的引用存储的位置,线程独立的。堆:大量运行时对象都在这个区域存储,线程共享的。方法区:存储运行时代码、类变量、常量池、构造器等信息,线程共享。程…...
固态存储设备固件升级方案
1. 前言 随着数字化时代的发展,数字数据的量越来越大,相应的数据存储的需求也越来越大,存储设备产业也是蓬勃发展。存储设备产业中,发展最为迅猛的则是固态存储(Solid State Storage,SSS)。数字化时代,海量…...
Python交通标志识别基于卷积神经网络的保姆级教程(Tensorflow)
项目介绍 TensorFlow2.X 搭建卷积神经网络(CNN),实现交通标志识别。搭建的卷积神经网络是类似VGG的结构(卷积层与池化层反复堆叠,然后经过全连接层,最后用softmax映射为每个类别的概率,概率最大的即为识别…...
基于Selenium+Python的web自动化测试框架(附框架源码+项目实战)
目录 一、什么是Selenium? 二、自动化测试框架 三、自动化框架的设计和实现 四、需要改进的模块 五、总结 总结感谢每一个认真阅读我文章的人!!! 重点:配套学习资料和视频教学 一、什么是Selenium? …...
Python进阶-----高阶函数zip() 函数
目录 前言: zip() 函数简介 运作过程: 应用实例 1.有序序列结合 2.无序序列结合 3.长度不统一的情况 前言: 家人们,看到标题应该都不陌生了吧,我们都知道压缩包文件的后缀就是zip的,当然还有r…...
win10打印机拒绝访问解决方法
一直以来,在安装使用共享打印机打印一些文件的时候,会遇到错误提示:“无法访问.你可能没有权限使用网络资源。请与这台服务器的管理员联系”的问题,那为什么共享打印机拒绝访问呢?别着急,下面为大家带来相关的解决方法…...
深度学习训练营之数据增强
深度学习训练营学习内容原文链接环境介绍前置工作设置GPU加载数据创建测试集数据类型查看以及数据归一化数据增强操作使用嵌入model的方法进行数据增强模型训练结果可视化自定义数据增强查看数据增强后的图片学习内容 在深度学习当中,由于准备数据集本身是一件十分复杂的过程,…...
Tomcat安装及启动
日升时奋斗,日落时自省 目录 1、Tomcat下载 2、JDK安装及配置环境 3、Tomcat配置环境 4、启动Tomcat 5、部署演示 1、Tomcat下载 直接入主题,下载Tomcat 首先就是别下错了,直接找官方如何看是不是广告,或者造假 搜索Tomc…...
【专项训练】排序算法
排序算法 非比较类的排序,基本上就是放在一个数组里面,统计每个数出现的次序 最重要的排序是比较类排序! O(nlogn)的3个排序,必须要会!即:堆排序、快速排序、归并排序! 快速排序:分治 经典快排 def quickSort1(arr...
Android压测测试事件行为参数对照表
执行参数参数说明颗粒度指标基础参数--throttle <ms> 用于指定用户操作间的时延。 -s 随机数种子,用于指定伪随机数生成器的seed值,如果seed值相同,则产生的时间序列也相同。多用于重测、复现问题。 -v 指定输出日志的级别,…...
【观察】亚信科技:“飞轮效应”背后的数智化创新“延长线”
著名管理学家吉姆柯林斯在《从优秀到卓越》一书中提出“飞轮效应”,它指的是为了使静止的飞轮转动起来,一开始必须使很大的力气,每转一圈都很费力,但达到某一临界点后,飞轮的重力和冲力就会成为推动力的一部分…...
QT编程从入门到精通之十四:“第五章:Qt GUI应用程序设计”之“5.1 UI文件设计与运行机制”之“5.1.1 项目文件组成”
目录 第五章:Qt GUI应用程序设计 5.1 UI文件设计与运行机制 5.1.1 项目文件组成 第五章:Qt GUI应用程序设计...
(二分)730. 机器人跳跃问题
目录 题目链接 一些话 切入点 流程 套路 ac代码 题目链接 AcWing 730. 机器人跳跃问题 - AcWing 一些话 // 向上取整 mid的表示要写成l r 1 >> 1即可,向下取整 mid l r >> 1 // 这里我用了浮点二分,mid (l r) / 2,最…...
vue3使用nextTick
发现nextTick必须放在修改一个响应式数据之后,才会在onUpdated之后被调用,如果nextTick是放在所有对响应式数据修改之前,则nextTick里面的回调函数会在onBeforeUpdate方法执行前就被调用了。可是nextTick必须等到onUpdated执行完成之后执行&a…...
传统图像处理之颜色特征
博主简介 博主是一名大二学生,主攻人工智能研究。感谢让我们在CSDN相遇,博主致力于在这里分享关于人工智能,c,Python,爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主,博主会继续更新的,…...
GPS问题调试—MobileLog中有关GPS关键LOG的释义
GPS问题调试—MobileLog中有关GPS关键LOG的释义 [DESCRIPTION] 在mobile log中,有很多GPS相关的log出现在main log和kernel log、properties文件中,他们的意思是什么,通过这篇文档进行总结,以便在处理GPS 问题时,能够根据这些log快速的收敛问题。 [SOLUTION] 特别先提醒…...
【企业管理】你真的理解向下管理吗?
导读:拜读陈老师一篇文章《不会向下负责,你凭什么做管理者?》,引发不少共鸣,“很多管理者有一种错误的观念,认为管理是向下管理,向上负责。其实应该反过来,是向上管理,向…...
Centos7 硬盘挂载流程
1、添加硬盘到Linux,添加后重启系统2、查看添加的硬盘,lsblksdb 8:16020G 0disk3、分区fdisk /dev/sdbmnw其余默认,直接回车再次查看分区情况,lsblksdb1 8:17 0 20G 0 part4、格式化mkfs -t ext4 /dev/sdb15、挂载mkdir /home/new…...
认识vite_vue3 初始化项目到打包
从0到1创建vite_vue3的项目背景效果vite介绍(对比和vuecli的区别)使用npm创建vitevitevuie3创建安装antdesignvite自动按需引入(vite亮点)请求代理proxy打包背景 vue2在使用过程中对象的响应式不好用新增属性的使用$set才能实现效…...
【Go】cron时间格式
【Go】cron时间格式 Minutes:分钟,取值范围[0-59],支持特殊字符* / , -;Hours:小时,取值范围[0-23],支持特殊字符* / , -;Day of month:每月的第几天,取值范…...
leetcode 55. 跳跃游戏
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示例 1: 输入:nums [2,3,1,1,4] 输出:true 解释:可以先跳 1 …...
Linux:文件流指针 与 文件描述符
目录一、文件描述符二、文件流指针三、缓冲区之前讲解过了IO库函数和IO接口,库函数是对系统调用接口的封装,也就是说实际上在库函数内部是通过调用系统调用接口来完成最终功能的。 库函数通过文件流指针操作文件,系统调用接口通过文件描述符操…...
基于FPGA实现正弦插值算法
1、正弦插值的算法分析 1.1 信号在时域与频域的映射关系 在进行正弦算法分析之前,我们回顾一下《数字信号处理》课程中,对于信号在时域与频域之间的映射关系,如下图。 对于上图中的原始信号x(t),使用ADC对信号进行采样࿰…...
JavaWeb_会话技术
文章目录会话跟踪技术的概述Cookie概念Cookie工作流程Cookie基本使用发送Cookie获取CookieCookie原理分析Cookie的使用细节Cookie的存活时间Cookie存储中文SessionSession的基本使用概念工作流程Session的基本使用Session的原理分析Session的使用细节Session的钝化与活化Sessio…...
Reactor响应式流的核心机制——背压机制
响应式流是什么? 响应式流旨在为无阻塞异步流处理提供一个标准。它旨在解决处理元素流的问题——如何将元素流从发布者传递到订阅者,而不需要发布者阻塞,或订阅者有无限制的缓冲区或丢弃。 响应式流模型存在两种基本的实现机制。一种就是传统…...
手机端网站设计制作案例/优化排名推广关键词
杭州市POI数据写在前面的话杭州市POI分类写在前面的话 POI是“Point of Interest”的缩写,中文意思为“兴趣点”,广义的POI可以指任何你想要研究的一系列对象。在地理信息系统中,一个POI可以是一个小区、一个地铁站、一个公交站,…...
建设银行官方网站诚聘英才频道/越秀seo搜索引擎优化
前言在我们访问网站的过程中,有时候会遇到您的连接不是私密连接。正常操作是点击高级,然后我们在继续访问,那么在selenium中,我们需要一步步定位?过程比较繁琐,最主要的是,有时候只有第一次才会…...
discuz视频网站模板/推广管理
在这里介绍手势识别目前情况: 目前手势识别的程序,在很多公开的网页上都能找到。直接百度“手势识别”即可。 比如说:https://www.cnblogs.com/demodashi/p/9437696.html。它是非人工智能手段。直接使用opencv来完成的。它的原理基本是基于边…...
如何开展网络营销/佛山网站优化软件
赛题 #A: P5461 赦免战俘 题目大意: 现有一个 $2^n\times 2^n (n\le10) $ 的正方形矩阵,初始时全部为1。现将正方形矩阵均分为 4 个更小的正方形矩阵,其中左上角那一个矩阵的所有元素变为0,剩下 3 个小矩阵中,每一个矩…...
wordpress网页怎么上传/郑州网站seo外包公司
创建一个104的sheet 清除9-10行,清除D列(注意:不是删除行/列) 测试代码 main() { ... Workbook workBook null; InputStream fin null; logger.info("sheet1 从10*4改成8*3后测试:"); fin new…...
电子商务网站开发过程/百度做免费推广的步骤
-----------------------建议与咨询请留言! -----------------------商务合作请私信! 9月大数据篇章,敬请期待! Thank You !!!...