JAVA8 Stream

news2024/11/18 2:22:17

1 Steam流式思想概述

Stream和IO流(InputStream/OutputStream)没有任何关系,请暂时忘记对传统IO流的固有印象!
Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种数据结构,不保存数据,而是对数据进行加工
处理。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。

在这里插入图片描述

Stream API能让我们快速完成许多复杂的操作,如筛选、切片、映射、查找、去除重复,统计,匹配和归约。

2 Stream流的获取方式

首先,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(); // key
        Stream<Object> stream1 = map.values().stream(); // value
        Stream<Map.Entry<String, Object>> stream2 = map.entrySet().stream(); // entry
}

3 Stream常用方法介绍

Stream常用方法
Stream流模型的操作很丰富,这里介绍一些常用的API。这些方法可以被分成两种:

方法名方法作用返回值类型方法种类
count统计个数long终结
forEach逐一处理void终结
filter过滤Stream函数拼接
limit取用前几个Stream函数拼接
skip跳过前几个Stream函数拼接
map映射Stream函数拼接
concat组合Stream函数拼接

终结方法:返回值类型不再是 Stream 类型的方法,不再支持链式调用。本小节中,终结方法包括 count 和 forEach 方法。

非终结方法:返回值类型仍然是 Stream 类型的方法,支持链式调用。除了终结方法外,其余方法均为非终结方法。

Stream注意事项(重要)

  1. Stream只能操作一次
  2. Stream方法返回的是新的流
  3. Stream不调用终结方法,中间的操作不会执行

3.1 forEach

遍历:

public static void main(String[] args) {
        List<String> words = Arrays.asList("Hello", "World");
        words.stream().forEach(System.out::println);
}

3.2 count

Stream流中的count方法用来统计其中的元素个数的:

public static void main(String[] args) {
        List<String> words = Arrays.asList("Hello", "World");
        //for each , count
        System.out.println(words.stream().count());
    }

3.3 filter

在这里插入图片描述

filter方法的作用是用来过滤数据的。返回符合条件的数据:

public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world", "window", "good", "nice");
        //for each , count
        words.stream().filter(o->o.startsWith("w")).forEach(System.out::println);
    }

在这里插入图片描述

3.4 map

如果我们需要将流中的元素映射到另一个流中,可以使用map方法:

在这里插入图片描述

public static void main(String[] args) {
        List<String> words = Arrays.asList("hello", "world", "window", "good", "nice");
        //for each , count
        words.stream().map(String::length).forEach(System.out::println);

    }

在这里插入图片描述

3.5 sorted

如果需要将数据排序,可以使用sorted方法:

public static void main(String[] args) {
        List<String> words = Arrays.asList("1", "22", "33", "20", "30");
        //for each , count
        words.stream().map(Integer::parseInt).sorted((n1, n2) -> n2 - n1).forEach(System.out::println);

    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ujsDWZEh-1684739478779)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1de44612-5ecf-445a-9365-7bcb0da5aed4/Untitled.png)]

3.6 distinct

如果要去掉重复数据,可以使用distinct方法:

在这里插入图片描述

public static void main(String[] args) {
        List<String> words = Arrays.asList("1", "22", "22", "19", "33", "20", "30");
        //for each , count
        words.stream()
                .distinct()
                .map(Integer::parseInt)
                .sorted((n1, n2) -> n2 - n1)
                .forEach(System.out::println);

    }

在这里插入图片描述

3.7 Max Min

在这里插入图片描述

public static void main(String[] args) {
        List<String> words = Arrays.asList("1", "22", "22", "19", "33", "20", "30");
        //for each , count
        Optional<Integer> max = words.stream().map(Integer::parseInt)
                .max((o1, o2) -> o1 - o2);
        System.out.println(max.get());

        Optional<Integer> min = words.stream().map(Integer::parseInt)
                .min((o1, o2) -> o1 - o2);
        System.out.println(min.get());

    }
public static void main(String[] args) {

        List<Person> peoples = Arrays.asList(
                new Person("r1", 12, 180),
                new Person("r2", 13, 180),
                new Person("r3", 14, 180)
        );

        Optional<Person> max = peoples.stream().max((o1, o2) -> o1.getAge() - o2.getAge());
        System.out.println(max.get());

    }

3.8 reduce

在这里插入图片描述

如果需要将所有数据归纳得到一个数据,可以使用reduce方法:

public static void main(String[] args) {

        List<Person> peoples = Arrays.asList(
                new Person("r1", 12, 180),
                new Person("r2", 13, 180),
                new Person("r3", 14, 180)
        );
        // 所有年龄
        Integer reduce = peoples.stream().map(Person::getAge).reduce(0, Integer::sum);
        System.out.println(reduce);

        // 最大值
        Integer maxAge = peoples.stream().map(Person::getAge).reduce(0, Integer::max);
        System.out.println(maxAge);

    }

在这里插入图片描述

4 Stream结果收集

4.1 流中数据收集

public static void main(String[] args) {

        List<String> list = Stream.of("aa", "bb", "cc", "aa")
                .collect(Collectors.toList());
        System.out.println(list);
        // 收集到 Set集合中
        Set<String> set = Stream.of("aa", "bb", "cc", "aa")
                .collect(Collectors.toSet());
        System.out.println(set);
    }

在这里插入图片描述

4.2 流中数据聚合计算

public static void main(String[] args) {

        // 获取年龄的最大值
        Optional<Person> maxAge = Stream.of(
                new Person("张三", 18)
                , new Person("李四", 22)
                , new Person("张三", 13)
                , new Person("王五", 15)
                , new Person("张三", 19)
        ).collect(Collectors.maxBy((p1, p2) -> p1.getAge() - p2.getAge()));
        System.out.println("最大年龄:" + maxAge.get());
        // 获取年龄的最小值
        Optional<Person> minAge = Stream.of(
                new Person("张三", 18)
                , new Person("李四", 22)
                , new Person("张三", 13)
                , new Person("王五", 15)
                , new Person("张三", 19)
        ).collect(Collectors.minBy((p1, p2) -> p1.getAge() - p2.getAge()));
        System.out.println("最新年龄:" + minAge.get());
        // 求所有人的年龄之和
        Integer sumAge = Stream.of(
                        new Person("张三", 18)
                        , new Person("李四", 22)
                        , new Person("张三", 13)
                        , new Person("王五", 15)
                        , new Person("张三", 19)
                )
                //.collect(Collectors.summingInt(s -> s.getAge()))
                .collect(Collectors.summingInt(Person::getAge))
                ;
        System.out.println("年龄总和:" + sumAge);
        // 年龄的平均值
        Double avgAge = Stream.of(
                new Person("张三", 18)
                , new Person("李四", 22)
                , new Person("张三", 13)
                , new Person("王五", 15)
                , new Person("张三", 19)
        ).collect(Collectors.averagingInt(Person::getAge));
        System.out.println("年龄的平均值:" + avgAge);
        // 统计数量
        Long count = Stream.of(
                        new Person("张三", 18)
                        , new Person("李四", 22)
                        , new Person("张三", 13)
                        , new Person("王五", 15)
                        , new Person("张三", 19)
                ).filter(p->p.getAge() > 18)
                .collect(Collectors.counting());
        System.out.println("满足条件的记录数:" + count);
    }

在这里插入图片描述

4.3 对流中数据做分组操作

当我们使用Stream流处理数据后,可以根据某个属性将数据分组

public static void main(String[] args) {

        List<Person> peoples = Arrays.asList(
                new Person("r1", 12),
                new Person("r2", 13),
                new Person("r3", 14)
        );

        Map<Integer, List<Person>> collect = peoples.stream().collect(Collectors.groupingBy(Person::getAge));

        System.out.println(collect);


    }

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue 3 第二十一章:组件九(组件高级特性-组件的混入和继承)

文章目录 1. 组件的混入2. 组件的继承总结 Vue 中的组件混入和继承功能允许我们在多个组件之间共享代码&#xff0c;从而提高代码的可重用性和可维护性。 1. 组件的混入 混入是一种将多个对象合并为一个对象的技术。在 Vue 3 中&#xff0c;我们可以使用 mixins 属性来定义混…

ThingsBoard的Actor模型

0、概述 下面是我从网上查阅资料总结下来的. 1、背景 多线程编程是每个程序员的基本功,同时也是开发中的难点,处理各种“锁”的问题是让人十分头痛的一件事。例如,设计一个转账功能,怎么保证在多线程下能正常运行?你可能会说,这个简单,在进行转账操作前,先对两个账户…

【实战项目】使用C语言和easyX,一起完成数字拼图游戏吧!快来挑战一下吧~

这款简易的拼图游戏包含了15个数字方块&#xff0c;你需要将它们按照顺序排列成1~15的数字&#xff0c;就能完成游戏。 在游戏中会记录你完成拼图所用的时间。我想强调的是&#xff0c;一个精彩的游戏并不一定需要使用图片。只要功能和手感都做得出色&#xff0c;游戏同样能够…

从0到1,深刻理解Linux权限

[Linux]深刻理解Linux权限 从0到1&#xff0c;深刻理解Linux权限Linux权限的概念Linux权限管理Linux文件访问者文件类型和访问权限文件类型访问权限 文件访问权限设置修改文件权限修改文件拥有者修改所属组 umask掩码目录权限目录权限问题粘滞位 权限总结&#xff1a; 从0到1&a…

1688商品详细信息价格SKU接口

随着新零售时代的到来&#xff0c;越来越多的企业开始关注电商平台&#xff0c;其中1688平台作为国内重要的B2B电商平台之一&#xff0c;对于企业发展、产品销售等方面有着重要的价值。在使用1688平台出售商品时&#xff0c;如何优化商品详情页、提高搜索排名、增加商品曝光度&…

PG15.3.0源码编译安装日志插件pgbadger(上)

一、开启相关日志 修改后alter一定要重启&#xff0c;才会修改 pg_ctl restart -D /usr/local/pgsql/data -l logfile按照下面的方法一个个修改。 log_destination csvlog # 可选 logging_collector on log_min_duration_statement 0 log_line_prefix %t [%p]: us…

(转载)MATLAB智能算法30个案例分析(2)——基于遗传算法和非线性规划的函数寻优算法

以下内容大部分来源于《MATLAB智能算法30个案例分析》&#xff0c;仅为学习交流所用。 1 理论基础 1.1 非线性规划 非线性规划是20世纪50年代形成的一门新兴学科。1951年库恩和塔克发表的关于最优性条件(后来称为库恩塔克条件)的论文是非线性规划诞生的标志。非线性规划研究…

聚会游戏玩什么?UMO轻松炒热气氛

UMO是一款有趣的多人益智桌游&#xff0c;考验玩家耐力和技巧的比拼&#xff01;玩家将在游戏中通过特定的规则来出牌&#xff0c;谁先出完所有牌谁就赢&#xff0c;游戏非常讲究策略和运气哦~ 当玩家手上只剩一张牌时&#xff0c;必须喊出UMO&#xff01;游戏因此得名。【数字…

自学网络安全,最应该先学的五大技能树是什么?(附学习路线图)

前言&#xff1a; 近几年网络安全事件频发&#xff0c;国家对于互联网信息安全和互联网舆情的重视程度不断提升有关&#xff0c;全球网络安全岗位缺口达500万&#xff0c;中国约100万&#xff0c;产业人才需求逐年增加&#xff0c;网络安全行业的相关岗位成为炙手可热的职业。…

COMSOL光电案列应用实操教学:

COMSOL多物理场仿真软件以高效的计算性能和杰出的多场耦合分析能力实现了精确的数值仿真&#xff0c;已被广泛应用于各个领域的科学研究以及工程计算&#xff0c;为工程界和科学界解决了复杂的多物理场建模问题。光电作为物理类专业课程中极为重要的一部分&#xff0c;其教学内…

如何做到设备维护事半功倍?

在工业生产过程中&#xff0c;设备故障可能导致生产停机、成本增加和安全风险。因此&#xff0c;及时监测设备的健康状况&#xff0c;预测潜在故障&#xff0c;并采取相应的维护措施至关重要。 振动在线监测系统是一种有效的工具&#xff0c;可以实时监测设备振动&#xff0c;并…

3. Linux下实现统计文件单词个数和出现次数

本文介绍的是在Linux下实现统计文件单词个数和出现次数&#xff0c;以及实践过程中遇到的gcc编译器不匹配问题 一、实现文件单词个数统计 #include <stdio.h>#define IN_Word 1 #define OUT_Word 0 #define INIT OUT_Wordint splite(char c){if ((c ) || (c\n) || (c\t…

ChatGPT ?、AI 和机器人,是为人类打工还是将取代人类?

随着ChatGPT引起全球热潮&#xff0c;我们看到这类AI大模型技术比较热门的落地领域聚焦在办公平台、家庭、电商营销、社交文娱等多个方向&#xff0c;又进一步向下渗透到生产和生活的各个环节。这些场景大多数聚焦于线上&#xff0c;涉及内容创作和交互方式变革两个方向&#x…

【全网首发】华秋CAM:免费Gerber查看器,离线版!

自华秋DFM可制造性和组装性分析软件上线以来&#xff0c;已为众多硬件工程师、PCB工程师、CAM工程师、电子爱好者、PCBA采购、SMT工厂等众多行业用户&#xff0c;解决了各种PCB设计隐患和规避各类生产风险等问题&#xff0c;并获得了30万用户的一致好评&#xff01; 现在&…

双非渣本测试,3个月逆袭字节,入职那天“泪目”了

个人背景情况 2017 年毕业于一所不知名双非本科大学&#xff0c;毕业时就有着一颗想进大厂的心&#xff0c;但又想留在成都&#xff0c;不愿意去北上广&#xff0c;现在其实相当后悔。当年在成都的大厂少之又少&#xff0c;再加上校招时非常努力地玩耍&#xff0c;导致投的几个…

全网独一份微服务架构深度解析,连京东师哥都熬夜也要看完

什么是微服务&#xff0c;为什么需要用微服务&#xff1f; 一、微服务是什么&#xff1f; 定义&#xff1a;微服务是一些协同工作的小而自治的服务&#xff0c;这个服务是高凝聚力和松散耦合的。 微服务有以下特征&#xff1a; 1.一组小的服务&#xff08;大写没有特别的标…

Linux之firewalld防火墙基础

目录 一、firewalld的简介 二、iptables与firewalld的联系与区别 1&#xff09;iptables与firewalld的联系 netfilter Firewalld/iptables 2&#xff09;iptables与firewalld的区别 区别一&#xff1a; 区别二&#xff1a; 区别三&#xff1a; 三、firewalld区域 1…

meta标签 http-equiv常用配置记录

meta标签 元素可提供有关页面的元信息&#xff08;meta-information&#xff09;&#xff0c;比如针对搜索引擎和更新频度的描述和关键词。 标签位于文档的头部&#xff0c;不包含任何内容。 标签的属性定义了与文档相关联的名称/值对。 属性 使用实例 禁止浏览器从本地机的缓…

涨姿势了,分享一个简单好用的源码调试方法

之前发了一篇文章&#xff0c;文章中有这样的一段描述&#xff1a; 然后有个读者来问我&#xff1a; 是怎么把 JDK 源码中的一行代码给注释掉的&#xff1f; 这个问题确实不错&#xff0c;属于一个偶尔用一下能起到奇效的源码调试技巧。所以我决定写个文章来说明一下这个问题。…

Mysql-存储过程简单入门

定义&#xff1a; 存储过程的英文是 Stored Procedure 。它的思想很简单&#xff0c;就是一组经过 预先编译 的 SQL 语句 的封装。 执行过程&#xff1a;存储过程预先存储在 MySQL 服务器上&#xff0c;需要执行的时候&#xff0c;客户端只需要向服务器端发出调用 存储过程的命…