jdk 03.stream
01.集合处理数据的弊端
当我们在需要对集合中的元素进行操作的时候,除了必需的添加,删除,获取外,最典型的操作就是集合遍历
package com.bobo.jdk.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StreamTest01 {public static void main(String[] args) {// 定义一个List集合List<String> list = Arrays.asList("张三","张三丰","成龙","周星驰");// 1.获取所有 姓张的信息List<String> list1 = new ArrayList<>();for (String s : list) {if(s.startsWith("张")){list1.add(s);}}// 2.获取名称长度为3的用户List<String> list2 = new ArrayList<>();for (String s : list1) {if(s.length() == 3){list2.add(s);}}for (String s : list2) {System.out.println(s);}}
}
上面的代码针对与我们不同的需求总是一次次的循环循环循环.这时我们希望有更加高效的处理方式,这时我们就可以通过JDK8中提供的Stream API来解决这个问题了。
Stream更加优雅的解决方案:
package com.bobo.jdk.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StreamTest02 {public static void main(String[] args) {// 定义一个List集合List<String> list = Arrays.asList("张三","张三丰","成龙","周星驰");// 1.获取所有 姓张的信息// 2.获取名称长度为3的用户// 3. 输出所有的用户信息list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(s->{System.out.println(s);});System.out.println("----------");list.stream().filter(s->s.startsWith("张")).filter(s->s.length() == 3).forEach(System.out::println);}
}
上面的SteamAPI代码的含义:获取流,过滤张,过滤长度,逐一打印。代码相比于上面的案例更加的简洁直观
0 2. Steam流式思想概述
注意:
Stream和IO流(InputStream/OutputStream)没有任何关系,请暂时忘记对传统IO流的固有印象!
Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种数据结构,不保存数据,而是对数据进行加工处理。
Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。
Stream API能让我们快速完成许多复杂的操作,如筛选、切片、映射、查找、去除重复,统计,匹配和归约。
0 3. Stream流的获取方式
1 根据Collection获取
首先,java.util.Collection 接口中加入了default方法stream,也就是说Collection接口下的所有的实现都可以通过steam方法来获取Stream流。
public static void main(String[] args) {List<String> list = new ArrayList<>();list.stream();Set<String> set = new HashSet<>();set.stream();Vector vector = new Vector();vector.stream();
}
但是Map接口别没有实现Collection接口,那这时怎么办呢?这时我们可以根据Map获取对应的key-value的集合。
public static void main(String[] args) {Map<String,Object> map = new HashMap<>();Stream<String> stream = map.keySet().stream(); // keyStream<Object> stream1 = map.values().stream(); // valueStream<Map.Entry<String, Object>> stream2 = map.entrySet().stream(); //entry
}
3.1 通过Stream的of方法
在实际开发中我们不可避免的还是会操作到数组中的数据,由于数组对象不可能添加默认方法,
所有Stream接口中提供了静态方法of
public class StreamTest05 {public static void main(String[] args) {Stream<String> a1 = Stream.of("a1", "a2", "a3");String[] arr1 = {"aa","bb","cc"};Stream<String> arr11 = Stream.of(arr1);Integer[] arr2 = {1,2,3,4};Stream<Integer> arr21 = Stream.of(arr2);arr21.forEach(System.out::println);// 注意:基本数据类型的数组是不行的int[] arr3 = {1,2,3,4};Stream.of(arr3).forEach(System.out::println);}
}
4.Stream常用方法介绍
Stream常用方法:
Stream流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:
终结方法:返回值类型不再是 Stream 类型的方法,不再支持链式调用。
本小节中,
终结方法包括count 和forEach 方法。 非终结方法:返回值类型仍然是 Stream 类型的方法,支持链式调用。
(除了终结方法外,其余方法均为非终结方法。)
Stream注意事项(重要)
- Stream只能操作一次
- Stream方法返回的是新的流
- Stream不调用终结方法,中间的操作不会执行
4.1 forEach
forEach用来遍历流中的数据的
void forEach(Consumer<? super T> action);
该方法接受一个Consumer接口,会将每一个流元素交给函数处理
void forEach(Consumer<? super T> action);public static void main(String[] args) {Stream.of("a1", "a2", "a3").forEach(System.out::println);;
}
4.2 count
Stream流中的count方法用来统计其中的元素个数的
long count();
该方法返回一个long值,代表元素的个数。
public static void main(String[] args) {long count = Stream.of("a1", "a2", "a3").count();System.out.println(count);
}
4.3 filter
filter方法的作用是用来过滤数据的。返回符合条件的数据
可以通过filter方法将一个流转换成另一个子集流
Stream<T> filter(Predicate<? super T> predicate);
该接口接收一个Predicate函数式接口参数作为筛选条件
public static void main(String[] args) {Stream.of("a1", "a2", "a3","bb","cc","aa","dd").filter((s)->s.contains("a")).forEach(System.out::println);
}
limit方法可以对流进行截取处理,支取前n个数据,
Stream<T> limit(long maxSize);
参数是一个long类型的数值,如果集合当前长度大于参数就进行截取,否则不操作:
public static void main(String[] args) {Stream.of("a1", "a2", "a3","bb","cc","aa","dd").limit(3).forEach(System.out::println);
}
4.5 skip
如果希望跳过前面几个元素,可以使用skip方法获取一个截取之后的新流:
Stream<T> skip(long n);
操作:
public static void main(String[] args) {Stream.of("a1", "a2", "a3","bb","cc","aa","dd").skip(3).forEach(System.out::println);
}
4.6 map
如果我们需要将流中的元素映射到另一个流中(或者说把集合中的元素都改变数据类型),可以使用map方法:
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的数据
public static void main(String[] args) {Stream.of("1", "2", "3","4","5","6","7")//.map(msg->Integer.parseInt(msg)).map(Integer::parseInt).forEach(System.out::println);
}
4.7 sorted
如果需要将数据排序,可以使用sorted方法:
Stream<T> sorted();
在使用的时候可以根据自然规则排序,也可以通过比较强来指定对应的排序规则
public static void main(String[] args) {Stream.of("1", "3", "2","4","0","9","7")//.map(msg->Integer.parseInt(msg)).map(Integer::parseInt)//.sorted() // 根据数据的自然顺序排序.sorted((o1,o2)->o2-o1) // 根据比较强指定排序规则.forEach(System.out::println);
}
4.8 distinct
如果要去掉重复数据,可以使用distinct方法:
Stream<T> distinct();
运行:
public static void main(String[] args) {Stream.of("1", "3", "3","4","0","1","7")//.map(msg->Integer.parseInt(msg)).map(Integer::parseInt)//.sorted() // 根据数据的自然顺序排序.sorted((o1,o2)->o2-o1) // 根据比较强指定排序规则.distinct() // 去掉重复的记录.forEach(System.out::println);System.out.println("--------");Stream.of(new Person("张三",18),new Person("李四",22),new Person("张三",18)).distinct().forEach(System.out::println);
}
Stream流中的distinct方法对于基本数据类型是可以直接出重的,但是对于自定义类型,我们是需要重写hashCode和equals方法来移除重复元素。
4.9 match
如果需要判断数据是否匹配指定的条件,可以使用match相关的方法
boolean anyMatch(Predicate<? super T> predicate); // 元素是否有任意一个满足条件
boolean allMatch(Predicate<? super T> predicate); // 元素是否都满足条件
boolean noneMatch(Predicate<? super T> predicate); // 元素是否都不满足条件
使用
public static void main(String[] args) {boolean b = Stream.of("1", "3", "3", "4", "5", "1", "7").map(Integer::parseInt)//.allMatch(s -> s > 0)//.anyMatch(s -> s >4).noneMatch(s -> s > 4);System.out.println(b);
}
4.10 find
如果我们需要找到某些数据,可以使用find方法来实现
Optional<T> findFirst();
Optional<T> findAny();
运行:
public static void main(String[] args) {Optional<String> first = Stream.of("1", "3", "3", "4", "5", "1","7").findFirst();System.out.println(first.get());Optional<String> any = Stream.of("1", "3", "3", "4", "5", "1","7").findAny();System.out.println(any.get());
}
4.11 max和min
如果我们想要获取最大值和最小值,那么可以使用max和min方法
Optional<T> min(Comparator<? super T> comparator);
Optional<T> max(Comparator<? super T> comparator);
运行:
public static void main(String[] args) {Optional<Integer> max = Stream.of("1", "3", "3", "4", "5", "1", "7").map(Integer::parseInt).max((o1,o2)->o1-o2);System.out.println(max.get());Optional<Integer> min = Stream.of("1", "3", "3", "4", "5", "1", "7").map(Integer::parseInt).min((o1,o2)->o1-o2);System.out.println(min.get());
}
4.12 reduce方法
如果需要将所有数据归纳得到一个数据,可以使用reduce方法
T reduce(T identity, BinaryOperator<T> accumulator);
public static void main(String[] args) {Integer sum = Stream.of(4, 5, 3, 9)// identity默认值// 第一次的时候会将默认值赋值给x// 之后每次会将 上一次的操作结果赋值给x, y就是每次从数据中获取的元素.reduce(0, (x, y) -> {System.out.println("x="+x+",y="+y);return x + y;});System.out.println(sum);// 获取 最大值Integer max = Stream.of(4, 5, 3, 9).reduce(0, (x, y) -> {return x > y ? x : y;});System.out.println(max);
}
4.13 map和reduce的组合
在实际开发中我们经常会将map和reduce一块来使用
public static void main(String[] args) {// 1.求出所有年龄的总和Integer sumAge = Stream.of(new Person("张三", 18), new Person("李四", 22), new Person("张三", 13), new Person("王五", 15), new Person("张三", 19)).map(Person::getAge) // 实现数据类型的转换.reduce(0, Integer::sum);System.out.println(sumAge);// 2.求出所有年龄中的最大值Integer maxAge = Stream.of(new Person("张三", 18), new Person("李四", 22), new Person("张三", 13), new Person("王五", 15), new Person("张三", 19)).map(Person::getAge) // 实现数据类型的转换,符合reduce对数据的要求.reduce(0, Math::max); // reduce实现数据的处理System.out.println(maxAge);
// 3.统计 字符 a 出现的次数Integer count = Stream.of("a", "b", "c", "d", "a", "c", "a").map(ch -> "a".equals(ch) ? 1 : 0).reduce(0, Integer::sum);System.out.println(count);
}
相关文章:

jdk 03.stream
01.集合处理数据的弊端 当我们在需要对集合中的元素进行操作的时候,除了必需的添加,删除,获取外,最典型的操作就是集合遍历 package com.bobo.jdk.stream; import java.util.ArrayList; import java.util.Arrays; import java.ut…...

“华为杯”研究生数学建模竞赛2018年-【华为杯】C题:对恐怖袭击事件记录数据的量化分析
目录 摘 要: 一、 问题背景与重述 1.1 问题背景 1.2 问题重述 二、 问题分析...

java8的reduce方法
在 Java 8 中,reduce 是一个流操作方法,用于将流中的元素按照指定的操作进行归约(reduce)操作,最终得到一个结果。 reduce 方法有三种重载形式: T reduce(T identity, BinaryOperator<T> accumulato…...

Mac发现有的软件不能上网的破解之法
1、Mac上打开终端 terminal ,获取 root 权限。 sudo -i 2、编辑 hosts 文件 vim /private/etc/hosts 3、找到被禁止软件的数据请求域名,然后删除相关行,快捷件dd,然后:wq保存退出 比如百度 127.0.0.1 pan.baidu.com ##sec 印…...

定时检测接口是否正常飞书告警脚本
第一版 支持多个接口地址,循环检测,定时每分钟执行一次脚本 告警效果 脚本 飞书机器人创建忽略跳过,各大协作平台大同小异拿出机器人hook地址 #!/bin/bash URL_LIST=(https://gatewaxxxxxxxxxxxxxxxxxx https://sandbox-gatexxxxxxxxxxxxxxxxxx)for URL in ${URL_LIST[*...

【MySQL】2、MySQL数据库的管理
常用 describe user; Field:字段名称 Type:数据类型 Null :是否允许为空 Key :主键 Type:数据类型 Null :是否允许为空key :主键 Default :默认值 Extra :扩展属性,例如:标志符列(标识了种子,增量/步长)1 2 id:1 3 5 …...

8086汇编test指令学习
Test指令将两个操作数进行逻辑与运算,并根据运算结果设置相关的标志位。Test的两个操作数不会被改变。运算结果在设置过相关标记位后会被丢弃。 TEST AX,BX 与 AND AX,BX 命令有相同效果,只是Test指令不改变AX和BX的内容,而AND指令会把结果保…...

简单js逆向案例(2)
文章目录 前文分析完整代码结尾 前文 本文章中所有内容仅供学习交流,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 分析 目标网址 aHR0cHM6Ly9zZWFyY2guYmlkY2VudGV…...

azure data studio SQL扩展插件开发笔记
node.js环境下拉取脚手架 npm install -g yo generator-azuredatastudio yo azuredatastudio 改代码 运行 调试扩展,在visual studio code中安装插件即可 然后visual studio code打开进行修改运行即可 image.png 运行后自动打开auzre data studio了, 下面…...

【二分】搜索旋转数组
文章目录 不重复数组找最小值,返回下标重复数组找最小值,返回下标不重复数组找target,返回下标重复数组找target,返回bool重复数组找target,返回下标 不重复数组找最小值,返回下标 class Solution {public …...
APSIM模型应用与参数优化、批量模拟
APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和Next Generation两个系列模型,能模拟几十种农作物、牧草和树木的土壤-植物-大气过程,被广泛应用于精细农业、水肥管理、气候变化、粮食安…...

QT使用QXlsx实现对Excel sheet的相关操作 QT基础入门【Excel的操作】
准备:搭建环境引用头文件QT中使用QtXlsx库的三种方法 QT基础入门【Excel的操作】_吻等离子的博客-CSDN博客 #include "xlsxdocument.h"QTXLSX_USE_NAMESPACE // 添加Xlsx命名空间(https://github.com/dbzhang800/QtXlsxWriter) or QXLSX_USE_NAMESPACE // 添加Xl…...

ARM DIY(四)WiFi 调试
文章目录 焊接打开内核编译选项重新编译内核烧录 && 运行 && 测试完善脚本测速手搓天线正式天线 焊接 换个粗点的风枪嘴,让热风覆盖 RTL8823BS 整体模块,最终实现自动归位 焊接 SDIO 接口的上拉电阻以及复位引脚上拉电阻 硬件部分就这…...

AIGC ChatGPT 实现动态多维度分析雷达图制作
雷达图在多维度分析中是一种非常实用的可视化工具,主要有以下优势: 易于理解:雷达图使用多边形或者圆形的形式展示多维度的数据,直观易于理解。多维度对比:雷达图可以在同一张图上比较多个项目或者实体在多个维度上的…...

Vue2向Vue3过度核心技术路由
目录 1 路由介绍1.思考2.路由的介绍3.总结 2 路由的基本使用1.目标2.作用3.说明4.官网5.VueRouter的使用(52)6.代码示例7.两个核心步骤8.总结 3 组件的存放目录问题1.组件分类2.存放目录3.总结 4 路由的封装抽离5 Vue路由-重定向1.问题2.解决方案3.语法4…...

ElasticSearch常用方法
ElasticSearch:是一个储存、检索、数据分析引擎。 在互联网项目中我们经常会按一定的条件去索引我们指定的数据,但是在大量的数据中我们如果直接查询数据库效率是非常低的,ElasticSearch就可以很好的帮我们完成检索。 es封装了api提供给我我们直接操作…...

nginx下添加http_ssl_module并且配置域名,指定端口
1.切换到源码包: cd /home/nginx-1.23.1 2.进行编译: ./configure --prefix/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module 3.配置完成后,运行命令: make make命令执行后,不要进行mak…...

【PHP】PHP变量
1、变量介绍 PHP 是一门弱类型语言,不必向 PHP 声明该变量的数据类型。PHP 会根据变量的值,自动把变量转换为正确的数据类型。在强类型的编程语言中,必须在使用变量前先声明(定义)变量的类型和名称。 <?php $x5;…...

KVM创建虚拟机可访问外网+可使用Xshell等工具连接
创建虚拟机时使用桥接网络模块即可,如下: 1、创建一个存储卷(虚拟机的磁盘) 2、创建虚拟机时选择网络 3、系统安装完成后配置固定IP地址 vi /etc/sysconfig/network-scripts/ifcfg-eth0ONBOOTyes BOOTPROTOstatic IPADDR16.32.15.60 GATEWAY16.32.15.2…...

数据库——Redis 没有使用多线程?为什么不使用多线程?
文章目录 Redis6.0 之后为何引入了多线程? 虽然说 Redis 是单线程模型,但是, 实际上,Redis 在 4.0 之后的版本中就已经加入了对多线程的支持。 不过,Redis 4.0 增加的多线程主要是针对一些大键值对的删除操作的命令&a…...

Node.JS教程
文章目录 Node.JSNode.js学习指南一、Node.js基础1.认识Node.js2.开发环境搭建3. 模块、包、commonJS3.1、为什么要有模块化开发?3.2、CommonJS规范3.3、 modules模块化规范写法 4.Npm&Yarn4.1、npm使用4.2、全局安装nrm4.3、yarn使用 持续更新中总结 Node.JS N…...

mysql表锁死怎么办?事务锁sql超时被锁死怎么办?
不要慌!不要慌!两句命令教你做人 一、mysql表锁死 1、查询所有进程: SHOW PROCESSLIST; 2、找到进程号kill掉 kill 3269987 2、事务锁 sql超时被锁死 1、查询所有执行中的sql select t.*,to_seconds(now())-to_seconds(t.trx_started) id…...

基于JSP+Servlet+mysql学生宿舍管理系统
基于JSPServletmysql学生宿舍管理系统 一、系统介绍二、功能展示四、其它1.其他系统实现五.获取源码 一、系统介绍 项目类型:Java web项目 项目名称:基于JSPServlet的学生宿舍管理系统[sushe] 项目架构:B/S架构 开发语言:Java…...

Enabling Large Language Models to Generate Text with Citations
本文是LLM系列的文章,针对《Enabling Large Language Models to Generate Text with Citations》的翻译。 使大语言模型能够生成带有引用的文本 摘要1 引言2 任务设置和数据集3 自动评估4 建模5 实验6 人类评估7 相关工作8 结论不足 摘要 大型语言模型(…...

Qt Qml实现仪表盘动画
Qt Qml代码实现的仪表盘动画 效果: Qt Qml 仪表盘动画 Qt Qml 代码实现仪表盘动画 Qt Qml 仪表盘动画 部分Qml代码: import QtQuick 2.0Item {width: 2 * radiusheight: 2 * radiusrequired property double radiusproperty double airspeed: 0propert…...

一次PostgreSQL复杂jsonb数据矫正过程分享
背景介绍 想看干货直接看最后的总结,其他流水账可以不看,也可以当故事看。 7月底我司某产品因故需要拉齐现场版本,其中某地版本较低,且曾经做过一些定制内容,升级前也未识别该情况,导致后续持续一个月不断…...

如何在App里拉起小程序?
什么是小程序运行时框架? FinClip 的小程序编程模型是分为多个页面,每个页面有自己的 template、CSS 和 JS,实际在运行的时候,业务逻辑的 JS 代码是运行在独立的 JavaScript 引擎中,每个页面的 template 和 CSS 是运行…...

函数式编程-Stream流学习第二节-中间操作
1 Stream流概述 java8使用的是函数式编程模式,如同它的名字一样,它可以用来对集合或者数组进行链状流式操作,让我们更方便的对集合或者数组进行操作。 2 案例准备工作 我们首先创建2个类一个作家类,一个图书类 package com.stream.model;…...

SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka)
一、spring cloud简介 spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。另外说明spring cloud是基…...

无涯教程-进程 - 组会话控制
在本章中,我们将熟悉进程组,会话和作业控制。 进程组(Process Groups ) - 进程组是一个或多个进程的集合,一个进程组由一个或多个共享相同进程组标识符(PGID)的进程组成。 会话(Sessions) - 它是各种进程组的集合。…...