Java jdk8新特性:Stream 流
一. Stream
1. Stream也叫Stream流,是jdk8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据。
2. 优势:Stream流大量的结合了lambda的语言风格来编程,提供了一种更加强大,更加简洁的方式操作集合或者数组中的数据。
3. 使用步骤:
① 获取Stream流
② Stream流常用的中间方法(支持链式调用)
③ Stream 流常见的终结方法
public static void main(String[] args) {//StreamList<String> list = new ArrayList<String>();Collections.addAll(list, "卡莎", "卡车", "泰坦", "璐璐", "卡拉", "卡卡卡", "伊泽");System.out.println(list);//[卡莎, 卡车, 泰坦, 璐璐, 卡拉, 卡卡卡, 伊泽]//list中方法 筛选数据List<String> list1 = new ArrayList<>();for(String str : list){if (str.contains("卡") && str.length() == 2){list1.add(str);}}System.out.println(list1);//[卡莎, 卡车, 卡拉]//使用stream流 筛选List<String> list2 = list.stream().filter(s -> s.contains("卡")).filter(s -> s.length() == 2).collect(Collectors.toList());System.out.println(list2);//v}
二. Stream的常用方法
1. 获取Stream流
| 方法 | 说明 | |
| Collection提供的获取Stream流 | default Stream<E> stream() | 获取当前集合的Stream流 |
| Arrays类提供的获取Stream流 | public static <T> Stream<T> stream(T[] array) | 获取当前数组的Stream流 |
| Stream提供的获取Stream流 | public static<T> Stream<T> of(T... values) | 获取当前接收数据的Stream流 |
public static void main(String[] args) {//1. 获取List集合的Stream流List<String> list = new ArrayList<String>();Collections.addAll(list, "卡莎", "卡车", "泰坦", "璐璐", "卡拉", "卡卡卡", "伊泽");//获取Stream流Stream<String> stream = list.stream();//2. 获取Set集合的Stream流Set<String> set = new HashSet<String>();Collections.addAll(set, "大宇", "朵朵", "欢欢", "麦琪");//获取Stream流Stream<String> stream1 = set.stream();stream1.filter(s -> s.contains("欢")).forEach(System.out::println);//3. 获取Map集合的Stream流Map<String, String> map = new HashMap<>();map.put("杨过", "小龙女");map.put("张无忌", "赵敏");map.put("郭靖", "黄蓉");map.put("令狐冲", "东方不败");// 获取Stream流 分开处理Set set2 = map.entrySet();Stream<String> keys = set2.stream();Collection<String> values = map.values();Stream<String> vas = values.stream();//统一处理Set<Map.Entry<String, String>> entry = map.entrySet();Stream<Map.Entry<String, String>> kvs = entry.stream();kvs.filter(k -> k.getKey().contains("张")).forEach(System.out::println);//4. 获取数组的Stream流String[] str = {"路马", "天天", "莱德", "落落"};//public static <T> Stream<T> stream(T[] array)Stream<String> stream2 = Arrays.stream(str);//public static<T> Stream<T> of(T... values)Stream<String> stream3 = Stream.of(str);
}
2. Stream流常见的中间方法
(1) 中间方法是指调用完成后返回新的Stream流,可以继续使用(支持链式编程)
| 常用方法 | 说明 |
| Stream<T> filter(Predicate<? super T> predicate) | 用于对流中的数据进行过滤 |
| Stream<T> sorted() | 对元素进行升序排序 |
| Stream<T> sorted(Comparator<? super T> comparator) | 对元素按照指定规则排序 |
| Stream<T> limit(long maxSize) | 获取前几个元素 |
| Stream<T> skip(long n) | 跳过前几个元素 |
| Stream<T> distinct() | 去除流中重复的元素 |
| <R> Stream<R> map(Function<? super T, ? extends R> mapper) | 对元素进行加工,并返回对应的新流 |
| static <T> Stream<T> concat(Stream a, Stream b) | 合并a和b两个流 |
public class Student{private String name;private int age;private double score;public Student() {}public Student(String name, int age, double score) {this.name = name;this.age = age;this.score = score;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +'}';}@Overridepublic boolean equals(Object o) {if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Double.compare(score, student.score) == 0 && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age, score);}
}
public static void main(String[] args) {List<Double> scores = new ArrayList<Double>();Collections.addAll(scores, 99.0, 96.0, 94.0,59.0, 66.0, 74.0);//成绩大于等于60的并排序scores.stream().filter(s -> s >= 60.0).sorted().forEach(System.out::println);//66.0 74.0 94.0 96.0 99.0System.out.println("--------------------------------------------");List<Student> students = new ArrayList<>();Student s1 = new Student("卡莎", 18, 99.0);Student s2 = new Student("泰坦", 19, 93.0);Student s3 = new Student("伊泽", 16, 98.0);Student s4 = new Student("璐璐", 14, 96.0);Student s5 = new Student("璐璐", 14, 96.0);Collections.addAll(students, s1, s2, s3, s4, s5);//找出年龄大于等于16 且小于等于20 按照年龄降序//filter() sorted()students.stream().filter(s -> s.getAge() >= 16 && s.getAge() <= 20).sorted(((o1, o2) -> o2.getAge() - o1.getAge())).forEach(System.out::println);System.out.println("--------------------------------------------");//找出分数最高的前三名// sorted() limit()students.stream().sorted((o1, o2) -> Double.compare(o2.getScore(), o1.getScore())).limit(3).forEach(System.out::println);System.out.println("--------------------------------------------");//找出分数最低的 倒数3名//sorted() skip()students.stream().sorted((o1, o2) -> Double.compare(o2.getScore(), o1.getScore())).skip(students.size() - 3).forEach(System.out::println);System.out.println("--------------------------------------------");//成绩大于等于95的 去除重复的名字// distinct() 自定义类型 如果希望内容一样认为重复 需重写 equals()和 hashCode()//filter() map() distinct()students.stream().filter(s -> s.getScore() >= 95).map(s -> s.getName()).distinct().forEach(System.out::println);students.stream().filter(s -> s.getScore() >= 95).distinct().forEach(System.out::println);//static <T> Stream<T> concat(Stream a, Stream b) 合并a和b两个流Stream<String> stream = Stream.of("1", "2", "3");Stream<String> stream2 = Stream.of("4", "5", "6", "7", "8", "9");Stream<String> stream3 = Stream.concat(stream, stream2);stream3.forEach(System.out::println);}
3. Stream流常见的终结方法
(1) 终结方法指的是调用完成后,不会再返回新的Stream流了,不能再继续使用Stream流了。
| 方法名称 | 说明 |
| void forEach(Consumer action) | 对此流运算后的元素进行遍历 |
| long count() | 统计此流运算后的元素个数 |
| Optional<T> max(Comparator<? super T> copmarator) | 获取此流运算后的最大值元素 |
| Optional<T> min(Comparator<? super T> copmarator) | 获取此流运算后的最小值元素 |
| 方法名称 | 说明 |
| R collect(Collector collector) | 把流处理后的结果放到一个指定的集合中 |
| Object[] toArray() | 把流处理后的结果放到一个指定的数组中 |
public static void main(String[] args) {List<Student> students = new ArrayList<>();Student s1 = new Student("卡莎", 18, 99.0);Student s2 = new Student("泰坦", 19, 93.0);Student s3 = new Student("伊泽", 16, 98.0);Student s4 = new Student("璐璐", 14, 96.0);Student s5 = new Student("璐璐", 14, 96.0);Collections.addAll(students, s1, s2, s3, s4, s5);// 计算分数超过95的有几个 .count()long l = students.stream().filter(s -> s.getScore() > 95).count();System.out.println(l);//4//找出分数最高的 并输出 .max()Student smax = students.stream().max((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();System.out.println(smax);//找出分数最低的 并输出 .min()Student smin = students.stream().min((o1, o2) -> Double.compare(o1.getScore(), o2.getScore())).get();System.out.println(smin);//计算分数超过95的 并放到一个新集合中//流只能收集一次List<Student> list1 = students.stream().filter(s -> s.getScore() > 95).collect(Collectors.toList());System.out.println(list1);Set<Student> list2 = students.stream().filter(s -> s.getScore() > 95).collect(Collectors.toSet());System.out.println(list2);//找出分数超过95的 并把名字和分数放到一个map集合中//不会自动去重 需调用distinct()去重Map<String, Double> map = students.stream().filter(s -> s.getScore() > 95).distinct().collect(Collectors.toMap(m -> m.getName(), m -> m.getScore()));System.out.println(map);//找出分数超过95的 并把名字和分数放到一个数组Object[] arr = students.stream().filter(s -> s.getScore() > 95).toArray();Student[] arr1 = students.stream().filter(s -> s.getScore() > 95).toArray(len -> new Student[len]);System.out.println(Arrays.toString(arr));System.out.println(Arrays.toString(arr1));
}
相关文章:
Java jdk8新特性:Stream 流
一. Stream 1. Stream也叫Stream流,是jdk8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据。 2. 优势:Stream流大量的结合了lambda的语言风格来编程,提供了一种更加强大,更加简洁的方式操作集合…...
房产销售系统(源码+数据库+文档)
亲测完美运行带论文:文末获取源码 文章目录 项目简介(论文摘要)运行视频包含的文件列表(含论文)前端运行截图后端运行截图 项目简介(论文摘要) 随着科学技术的飞速发展,各行各业都在…...
Vue 项目自动化部署:Coding + Jenkins + Nginx 实践分享
前言 本文详细记录如何使用 Coding (以 Jenkinsfile 为核心) 和 Nginx 部署 Vue 项目,包含完整流程、配置细节及注意事项,为开发者提供一个高效的实践参考。 准备工作 这里借用一个优秀的开源项目做演示:芋道源码/yudao-ui-admin-vue2。 以…...
从零开始开发纯血鸿蒙应用之实现起始页
从零开始开发纯血鸿蒙应用 一、前言二、主要页面三、应用起始页四、MainPageContent 实现1、一级结构2、二级结构2.1、EmptyContent2.2、FileListContent2.2.1、ViewAction:2.2.2、EditAction2.2.3、DeleteAction2.2.4、ShareAction 五、载入起始页的时机五、总结 一…...
CG顶会论文阅读|《科技论文写作》硕士课程报告
文章目录 一、基本信息1.1 论文基本信息1.2 课程基本信息1.3 博文基本信息 二、论文评述(中英双语)2.1 研究问题(Research Problem)2.2 创新点(Innovation/Contribution)2.3 优点(Why this pape…...
【Python运维】使用Python与Docker进行高效的容器化应用管理
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着容器化技术的广泛应用,Docker已成为现代软件开发与运维中不可或缺的工具。Docker容器提供了一种轻量级、可移植的方式来部署和管理应用…...
【人工智能】基于Python与OpenCV构建简单车道检测算法:自动驾驶技术的入门与实践
《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着自动驾驶技术的快速发展,车道检测作为自动驾驶系统中的一个重要组成部分,起着至关重要的作用。本文将介绍如何利用Python与OpenCV库构…...
实时数仓: Hudi 表管理、Flink 性能调优或治理工具脚本
1. Hudi 表管理 1.1 Hudi 表基础管理 创建 Hudi 表 在 HDFS 上创建一个 Hudi 表(以 Merge-on-Read 为例): CREATE TABLE real_time_dw.dwd_order_fact (order_id STRING,user_id STRING,product_id STRING,amount DOUBLE,order_date STRIN…...
Kotlin 数据类与密封类
Kotlin 数据类与密封类 引言 在 Kotlin 中,数据类和密封类是两种非常重要的类类型,它们各自具有独特的用途和优势。数据类主要用于存储数据,而密封类则用于表示受限的类层次结构。在本篇文章中,我们将深入探讨 Kotlin 中的数据类…...
大模型推理加速调研(框架、方法)
大模型推理加速调研(框架、方法) 大模型推理框架调研总结推理框架TensorRT-LLMllama.cppmnn-llmfastllmmlc-llm 环境搭建&部署推理环境llama.cppfastllmmnn-llmvllm vllm_openai_completions.pylmdeployTensorRT-LLM 大模型加速技术总结模型压缩量化…...
C语言进阶(3)--字符函数和字符串函数
本章重点 重点介绍处理字符和字符串的库函数的使用和注意事项 目录 0.前言 1.函数介绍 1.1 strlen - 计算字符串长度 1.2 strcpy - 复制字符串 1.3 strcat - 追加字符串 1.4 strcmp - 字符串比较 1.5 strncpy - 受限制复制 1.6 strncat - 受限制追加 1.7 strncmp - 受限制比…...
微服务拆分的艺术:构建高效、灵活的系统架构
目录 一、微服务拆分的重要性 二、微服务拆分的策略 1. 按照业务领域拆分 2. 按照团队结构拆分 3. 按照业务边界拆分 4. 按照数据和数据库拆分 5. 按照用户界面或外部接口拆分 6. 按照功能模块或领域驱动设计拆分 7. 按照性能和可伸缩性需求拆分 三、微服务拆分的实践…...
记录一次电脑被入侵用来挖矿的过程(Trojan、Miner、Hack、turminoob)
文章目录 0、总结1、背景2、端倪3、有个微软的系统更新,就想着更新看看(能否冲掉问题)4、更新没成功,自动重启电脑5、风险文件(好家伙命名还挺规范,一看名字就知道出问题了)6、开机有一些注册表…...
计算机xinput1_4.dll丢失怎么修复?
电脑运行时常见问题及修复指南 作为软件开发从业者,深知电脑在日常使用中难免会遇到各种问题,如文件丢失、文件损坏和系统报错等。这些问题不仅影响工作效率,还可能带来数据丢失的风险。本文将详细介绍一些常见问题及其解决办法,…...
高等数学学习笔记 ☞ 连续函数的运算与性质
1. 连续函数的运算 1. 连续函数的四则运算: (1)若函数在点处连续,则函数在点处也连续。 (2)若函数在区间上连续,则函数在区间上也连续。 2. 反函数的连续性: 若函数在定义域上是单…...
k8s基础(4)—Kubernetes-Service
Service概述 抽象层 k8s的Service是一种抽象层,用于为一组具有相同功能的Pod提供一个统一的入口地址,并通过负载均衡将网络流量分发到这些Pod上。 Service解决了Pod动态变化的问题,例如Pod的IP地址和端口可能会发生变化,通过…...
CAN或者CANFD的Busoff的恢复时间会受到报文周期的影响么?
目录 分析恢复机制角度快恢复和慢恢复策略角度特殊情况分析分析 Busoff的恢复时间通常不会直接受到报文周期的影响,以下是具体分析: 恢复机制角度 CAN总线的节点在Busoff状态下,恢复过程主要是等待总线上出现128个连续的11bit隐性位,与报文周期并无直接关联。无论报文周…...
【DevOps】Jenkins部署
Jenkins部署 文章目录 Jenkins部署资源列表基础环境一、部署Gilab1.1、安装Gitlab1.2、修改配置文件1.3、加载配置文件1.4、访问Gitlab1.5、修改root登录密码1.6、创建demo测试项目1.7、上传代码1.8、验证上传的代码 二、部署Jenkins所需软件2.1、部署JDK2.2、部署Tomcat2.3、部…...
【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型(敏感性分析方法)
【MATLAB第112期】基于MATLAB的SHAP可解释神经网络回归模型(敏感性分析方法) 引言 该文章实现了一个可解释的神经网络回归模型,使用BP神经网络(BPNN)来预测特征输出。该模型利用七个变量参数作为输入特征进行训练。为…...
【Shell编程 / 4】函数定义、脚本执行与输入输出操作
文章目录 函数 与 脚本定义函数示例:简单的 Shell 函数函数参数返回值 脚本执行创建脚本执行脚本 输入输出输出:echo 和 printf输入:read 命令 命令行参数示例:传递参数 函数 与 脚本 在 Shell 编程中,函数和脚本是组…...
保姆级教程:在Ubuntu 20.04上为RISC-V芯片编译运行CoreMark(含多线程配置)
RISC-V平台CoreMark性能测试全流程实战指南 在嵌入式开发领域,处理器性能评估始终是硬件选型和系统优化的关键环节。CoreMark作为当前最权威的嵌入式CPU基准测试工具,其测试结果已成为衡量RISC-V处理器性能的黄金标准。本文将完整演示如何在Ubuntu 20.04…...
Redis如何在应用启动时预热缓存数据
不可靠。应用启动时直接调用 redis-cli 或客户端批量写入易因 Redis 未就绪、网络不通、认证失败等导致失败,且缺乏重试、超时、幂等控制;应优先在应用层用客户端实现预热,并做好健康检查、分批写入与内存管控。应用启动时调用 redis-cli 或客…...
普冉001休眠配置
/********************************************************* PY001休眠函数详解 *********************************************************/ /********************************************************* * 函数名: MCU_Sleep * 说 明: 休眠函数 * 输 入: 无 …...
Highcharts 散点图:深入解析与最佳实践
Highcharts 散点图:深入解析与最佳实践 引言 散点图(Scatter Plot)是一种常用的数据可视化工具,它通过在二维坐标系中展示数据点来揭示变量之间的关系。Highcharts 是一个功能强大的 JavaScript 图表库,它支持多种图表类型,包括散点图。本文将深入探讨 Highcharts 散点…...
ESP32 SPI读写SD卡实战:从硬件连接到FATFS文件操作,一篇搞定所有坑
ESP32 SPI读写SD卡实战:从硬件连接到FATFS文件操作,一篇搞定所有坑 在嵌入式开发中,SD卡存储是扩展设备数据容量的常见方案。ESP32作为一款高性价比的Wi-Fi/蓝牙双模芯片,其SPI接口与SD卡的配合使用尤为广泛。本文将带你从硬件连…...
DCDC电源轻载时‘滋滋’叫?一文讲透PSM、Burst、FCM三种模式的选择与避坑
DCDC电源轻载啸叫难题:三种工作模式的深度解析与工程实践 引言 在电源设计领域,DCDC转换器的轻载啸叫问题堪称"幽灵故障"——它时隐时现,难以捉摸,却又实实在在地影响着产品品质。当你在深夜实验室调试电路板时…...
实战指南:从零到一掌握Logit回归全流程
1. 什么是Logit回归?它能解决什么问题? 第一次接触Logit回归时,我也被这个专业名词吓到了。后来在实际项目中用了才发现,它其实就是处理分类问题的利器。简单来说,当你的因变量Y是"是/否"、"买/不买&qu…...
【PyTorch实战】CrossEntropyLoss:从数学原理到代码避坑指南
1. 交叉熵损失函数的前世今生 我第一次接触CrossEntropyLoss是在做一个图像分类项目的时候。当时模型训练总是出问题,损失值波动特别大,后来才发现是没搞明白这个损失函数的输入格式要求。交叉熵本质上是一种衡量两个概率分布差异的方法,在分…...
SuperMap iDesktopX 实战:三步解锁高德POI数据,赋能地理信息应用
1. 为什么你需要掌握高德POI数据获取技能 作为一名GIS分析师或数据工程师,相信你经常遇到这样的场景:老板突然要求分析某区域的商业分布情况,或者规划部门急需某类公共设施的服务覆盖范围报告。这时候,POI(Point of In…...
从梯度泄露到数据复原:DLG与iDLG算法实战解析
1. 梯度泄露风险:联邦学习的阿喀琉斯之踵 想象一下这样的场景:医院A有患者的CT影像数据,医院B有对应的诊断报告,两家机构想联合训练一个AI诊断模型,但谁也不愿意直接共享原始数据。这时候联邦学习(Federate…...
