Java8 Stream流详解

文章目录

  • 概念和特点
  • 基本流程
  • 常见操作
    • 过滤(filter)
    • 映射(map)
    • 收集(collect)
    • 归约(reduce)
    • 扁平映射(flatMap)
  • java案例详解
  • 注意事项

概念和特点

Java中的Stream是用于处理集合数据的功能强大且灵活的API。Stream 是 Java 8 引入的一个新特性,它允许以函数式编程的方式来处理集合数据。通过使用 Stream可以写出更简洁、意图明确的代码,并且可以利用多核处理器的优势来并行处理数据,提高程序性能。

在这里插入图片描述

基本流程

  1. 首先需要将集合转换为 Stream, 可以从很多种数据源中创建Stream,例如List、Set或者任何其他实现了Iterable接口的类。创建方式很简单,使用stream()或parallelStream()方法即可。
  2. 然后通过中间操作对 Stream 进行一系列的处理。常用的Stream操作包括:过滤、映射、排序、去重、计数、归约等等。
  3. 最终通过终止操作得到处理结果。

常见操作

常用的Stream操作包括:过滤、映射、排序、去重、计数、归约等等。

在这里插入图片描述

过滤(filter)

根据条件筛选出符合条件的元素,过滤方法filter用于对Stream中的元素进行筛选,只保留符合指定条件的元素。其函数式接口为Predicate,其方法为boolean test(T t),接受一个T类型的对象,并返回一个boolean类型值。当该方法返回true时,说明该元素符合条件,将被保留在Stream中.

映射(map)

将 Stream 中的每个元素转换成另一种形式。映射方法map用于将Stream中的元素根据指定规则进行转换。其函数式接口为Function<T, R>,其方法为R apply(T t),接受一个T类型的对象,并返回一个R类型的对象。实质上,map方法就是对Stream中各元素做一个同类型的映射

收集(collect)

将 Stream 中的元素收集到如 List、Set 或 Map 等集合中。

归约(reduce)

将 Stream 中的元素组合起来生成一个值。

扁平映射(flatMap)

将 Stream 中的每个元素转换为另一个 Stream,然后合并为一个 Stream。

java案例详解

package cn.hyperchain.liststream;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author zhu
 * @Date 2022/1/7 11:14 AM
 * JAVA8 新特性:stream流操作集合
 * 案例:查询集合中age<20的学生,并且根据年龄进行排序,得到学生的姓名,生成新的集合
 */
//@SpringBootTest
public class ListStreamTest {
    private static List<Student> students = null;

    static {
        students = new ArrayList<>();
        students.add(new Student(1, "张三", "M", 19));
        students.add(new Student(2, "李四", "M", 18));
        students.add(new Student(3, "王武", "F", 21));
        students.add(new Student(4, "赵六", "F", 20));

        students.add(new Student(1, "张三", "M", 19));
        students.add(new Student(2, "李四", "M", 18));
        students.add(new Student(3, "王武", "F", 21));
        students.add(new Student(4, "赵六", "F", 20));
    }

    /**
     * 0. List stream流基本操作
     */
    @Test
    public void testStream() {
        // 案例一:
        List<String> res = students.stream()
                .filter(student -> student.getAge() < 20)       // 集合中age<20
                .distinct()                                     // 对象去重
                .sorted(Comparator.comparing(Student::getAge))  // 根据年龄进行排序
                .map(Student::getName)                          // 得到学生的姓名[可以有多个字段,但是需要封装]
                .collect(Collectors.toList());                  // 生成新的集合
        System.out.println("res = " + res);

        // 案例二:
        List<Integer> list = Arrays.asList(1, 1, 3, 43, 12, 43, 32, 1, 42, 3, 32, 43);
        List<Integer> result = list.stream()    // 1, 1, 3, 43, 12, 43, 32, 1, 42, 3, 32, 43
                .distinct()             // 去重           1,3,43,12,32,42
                .limit(5)               // 集合大小为5     1,3,43,12,32
                .skip(2)                // 跳过前2个元素    43,12,32
                .collect(Collectors.toList());
        System.out.println("result = " + result);
    }

    /**
     * 1. List stream流快速取集合元素某一个属性或多个属性,并转为List、Map、Set
     */
    @Test
    public void testMap() {
        // 1. List快速取一个字段为List
        List<Integer> ids = students.stream().map(Student::getId).collect(Collectors.toList());
        ids.forEach(System.out::println);

        // 2. List快速取多个字段组成一个Entity为List
        List<StudentDTO> dtos = students.stream()
                .map(new Function<Student, StudentDTO>() {  // 封装students的某些属性,函数式编程,Function已声明为@FunctionalInterface,此时作为参数传递,主要进行类型转换
                    @Override
                    public StudentDTO apply(Student student) {
                        return StudentDTO.builder()
                                .id(student.getId())
                                .name(student.getName())
                                .build();
                    }
                })
                .collect(Collectors.toList());
        System.out.println("dtos = " + dtos);

        // 3. List快速取Map
        Map<Integer, Student> map = students.stream().collect(Collectors.toMap(Student::getId, Function.identity())); // Function.identity() 表示直接返回对应的 DeviceExtendDto 对象作为 Value

        // 4. List快速取Set:值不可重复,List值可重复
        Set<Integer> set = students.stream().map(Student::getId).collect(Collectors.toSet());
        System.out.println("set = " + set);

        // 5. 分组为Map
//        Map<AttrTypeEnum, List<T2>> attrMap = attrs.stream().filter(t -> AttrTypeEnum.DEVICE != t.getType()).collect(Collectors.groupingBy(T2::getType));
    }

    /**
     * 2. List stream流快速判断Predicate
     */

    @Test
    public void testMatch() {
        // 写法一:testAnyMatch[判断集合任一个元素满足要求]
        boolean b1 = students.stream()
                .distinct()
                .anyMatch(new Predicate<Student>() {  // 匹配 anyMatch
                    @Override
                    public boolean test(Student student) {
                        return student.getName().equals("张三");
                    }
                });
        System.out.println("b1 = " + b1);

        // 写法二:testAnyMatch
        boolean b2 = students.stream()
                .distinct()
                .anyMatch(student -> student.getName().equals("张三"));
        System.out.println("b2 = " + b2);
    }

    @Test
    public void testFind() {
        Optional<Student> studentOptional = students.stream()
                .distinct()
//                .findAny();     // 随机获取一个元素
                .findFirst();     // 获取第一个元素
        if (studentOptional.isPresent()) {
            Student student = studentOptional.get();
            System.out.println("student = " + student);
        }
    }
}

注意事项

Stream 不会自己存储元素,也不会改变源对象。它会返回一个新的 Stream,这个新的 Stream 持有之前所有操作的结果。
Stream 的操作是延迟执行的,只有在真正需要结果的时候才会执行这些操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/457810.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Qt 线程池 QThreadPool

一.Qt 线程池 QThreadPool介绍 Qt线程池是一种管理多个线程的并发编程模型&#xff0c;通过使用线程池可以提高性能、控制并发度、提供任务队列和简化线程管理。 在Qt中&#xff0c;线程池的使用主要涉及以下几个步骤&#xff1a; 创建任务类&#xff1a;需要定义一个任务类&am…

PGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发,提供3套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收OSD动态字符叠加输出应用本方案的SDI接收HLS多路视频融…

AJAX 03 XMLHttpRequest、Promise、封装简易版 axios

AJAX 学习 AJAX 3 原理01 XMLHttpRequest① XHR 定义② XHR & axios 关系③ 使用 XHR④ XHR查询参数案例&#xff1a;地区查询&#xff08;URLSearchParams&#xff09;⑤ XHR数据提交 POST 02 PromisePromise 使用Promise - 三种状态案例&#xff1a;使用Promise XHR 获取…

sqllab第二十一关通关笔记

知识点&#xff1a; 错误注入 最大长度为32超过需要利用截取函数分段读取cookie注入base64加密会保留符号的原始属性 通过admin admin进行登录发现和第二十关显示的内容一样&#xff0c;猜测应该还是cookie注入&#xff1b; 直接截取带有cookie的数据包&#xff0c;发现uname…

SpringBoot异常:类文件具有错误的版本 61.0, 应为 52.0的解决办法

问题&#xff1a; java: 无法访问org.mybatis.spring.annotation.MapperScan 错误的类文件: /D:/Program Files/apache-maven-3.6.0/repository/org/mybatis/mybatis-spring/3.0.3/mybatis-spring-3.0.3.jar!/org/mybatis/spring/annotation/MapperScan.class 类文件具有错误的…

YOLO_项目环境配置

YOLOv5官方项目地址 https://github.com/ultralytics/yolov5 下载 5.0和1.0源码 5.0 master-Tags-v5.0 Code-Download.ZIP 切换到1.0下载 解压缩提取 打开V5.0 使用Pycharm打开V5.0的文件夹 环境配置 参考 http://t.csdnimg.cn/Zdfh2 http://t.csdnimg.cn/Nqkwr 然后在Pyc…

AVCE - AV Evasion Craft Online 更新 8 种加载方式 - 过 WD 等

免责声明&#xff1a;本工具仅供安全研究和教学目的使用&#xff0c;用户须自行承担因使用该工具而引起的一切法律及相关责任。作者概不对任何法律责任承担责任&#xff0c;且保留随时中止、修改或终止本工具的权利。使用者应当遵循当地法律法规&#xff0c;并理解并同意本声明…

Redis:持久化、线程模型、大 key

Redis持久化方式有什么方式&#xff1f; Redis 的读写操作都是在内存中&#xff0c;所以 Redis 性能才会高&#xff0c;但是当 Redis 重启后&#xff0c;内存中的数据就会丢失&#xff0c;那为了保证内存中的数据不会丢失&#xff0c;Redis 实现了数据持久化的机制&#xff0c…

Linux的一些常用指令

一、文件中 r w x - 的含义 r&#xff08;read&#xff09;是只读权限&#xff0c; w&#xff08;write&#xff09;是写的权限&#xff0c; x&#xff08;execute&#xff09;是可执行权限&#xff0c; -是没有任何权限。 二、一些指令 # 解压压缩包 tar [-zxvf] 压缩包名…

【计算机网络】概述

文章目录 一、Internet 因特网1.1 网络、互联网、因特网1.2 因特网的组成 二、三种交换方式2.1 电路交换 &#xff08;Circuit Switching&#xff09;2.2 *分组交换 &#xff08;Packet Switching&#xff09;2.3 报文交换 &#xff08;Message Switching&#xff09; 三、计算…

2023版IDEA永久破解教程带patch.exe破解程序

2023版IDEA永久破解教程带patch.exe破解程序 第零步&#xff1a;百度云盘获取程序第一步&#xff1a;关闭电脑的病毒和危险防护&#xff08;目的是避免电脑自动清除破解程序&#xff09;1.找到电脑的 病毒和威胁防护2.蓝色按钮表示防护处于开启状态3.关闭成功会展示“实时保护已…

Ansible非标记语言YAML与任务剧本Playbook

前言 上篇介绍了 Ansible 单模块&#xff08;AD-Hoc&#xff09;的相关内容Ansible自动化运维Inventory与Ad-Hoc-CSDN博客&#xff0c;Ad-Hoc 命令是一次性的、即时执行的命令&#xff0c;用于在远程主机上执行特定任务&#xff0c;这些命令通常用于快速执行简单的任务。当需要…

软件无线电系列——模拟无线电、数字无线电、软件无线电

本节目录 一、模拟无线电 二、数字无线电 1、窄带数字无线电 2、宽带数字无线电 三、软件无线电本节内容 一、模拟无线电 20世纪80年代的模拟体制(美国的AMPS/欧洲的TACS)被称为第一代移动通信&#xff0c;简称1G,主要目标是为在大范围内有限的用户提供移动电话服务。最主要的…

React——react 的基本使用

前提&#xff1a;安装全局的脚手架&#xff0c;通过create-creat-app 项目名&#xff0c;我们创建好一个新项目&#xff0c;cd进去&#xff0c;通过npm start去运行该项目 注意&#xff1a;简单看下demo的配置&#xff0c;在根目录我们可以看到&#xff0c;没有任何webpack的…

【b站咸虾米】2 Vue基础(下) 2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例

课程地址&#xff1a;【2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例】 https://www.bilibili.com/video/BV1pz4y1S7bC/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 2 Vue基础 下 2.8 计算属性 2.8.1 计算属性使用 2.8.2 计算…

整型变量的原子操作

什么是原子操作 原子操作&#xff08;Atomic Operation&#xff09;是指不可中断的操作&#xff0c;即在多线程环境下&#xff0c;当一个线程在执行原子操作时&#xff0c;不会被其他线程的调度和中断所影响。这种操作在多线程编程中尤为重要&#xff0c;因为它能保证操作的原…

Git如何清除账户凭证

场景&#xff1a;一般发生在Git用户变更的情况 1.git base 操作 Git会使用凭证助手 credential.helper来储存账户凭证&#xff0c;通过以下命令移除&#xff1a; git config --system --unset credential.helper 除了system系统级外&#xff0c;还有 global、local范围。 查…

直方图均衡化原理和实现

基本思想 将原始图像的直方图分布转换为一个均匀分布的直方图&#xff0c;这样原图中的高频率亮度值会被展宽&#xff0c;而低频率亮度值则被压缩&#xff0c;从而达到增强图像对比度的效果。 计算过程 假设我们有一个灰度图像&#xff0c;其像素值范围从0到L-1&#xff08;…

云计算 3月11号 (NFS远程共享存储及vsftpd配置)

构建NFS远程共享存储 一、NFS介绍 文件系统级别共享&#xff08;是NAS存储&#xff09; --------- 已经做好了格式化&#xff0c;可以直接用。 速度慢比如&#xff1a;nfs&#xff0c;sambaNFS NFS&#xff1a;Network File System 网络文件系统&#xff0c;NFS 和其他文件…

关于使用elementUI中select和el-checkbox-group的回显问题

网上看到很关于这个的问题回显&#xff0c;各式各样&#xff0c;没有绝句自己的问题&#xff0c;总重问题出在数据格式上 select和el-checkbox-group el-checkbox 都是字符串数组格式&#xff1a;[12,13,....]; 我写的格式是id是选中的id组成的回显数据格式&#xff1b; 如…