Java——Stream流的学习

在开发过程中,经常或忽略流的使用,导致用的不熟练,于是抽时间系统的学习下stream的使用,找了哔哩哔哩的教程跟着看看练练。

准备工作

创建Book、Aurhor实体类,初始化数据

public static List<Author> getAuthors() {Author author1 = new Author(1L, "蒙多", 33, "一个从菜刀中明悟哲理的祖安人", null);Author author2 = new Author(2L, "亚拉索", 15, "狂风也追逐不上他的思考速度", null);Author author3 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);Author author4 = new Author(3L, "易", 14, "是这个世界在限制他的思维", null);List<Book> books1 = new ArrayList<>();List<Book> books2 = new ArrayList<>();List<Book> books3 = new ArrayList<>();books1.add(new Book(1L, "刀的两侧是光明与黑暗", "哲学,爱情", 88, "用一把刀划分了爱情"));books1.add(new Book(2L, "一个人不能死在同一把刀下", "个人成长,爱情", 99, "讲述如何成功"));books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));books2.add(new Book(3L, "那风吹不到的地方", "哲学", 85, "带你用思维去领略世界的尽头"));books2.add(new Book(4L, "吹或不吹", "爱情,个人传记", 65, "一个哲学家的恋爱观注定很难"));books3.add(new Book(5L, "你的剑就是我的剑", "爱情", 56, "无法想象一个武者"));books3.add(new Book(5L, "风与剑", "个人传记", 100, "两个哲学家灵魂与肉体的碰撞"));books3.add(new Book(5L, "风与剑", "个人传记", 100, "两个哲学家灵魂与肉体的碰撞"));author1.setBooks(books1);author2.setBooks(books2);author3.setBooks(books3);author4.setBooks(books3);List<Author> authors = new ArrayList<>(Arrays.asList(author1, author2, author3, author4));return authors;}

创建流

// 1.单列集合
private static void test01(List<Author> authors) {authors.stream().distinct().filter(author -> author.getAge()<18).forEach(author -> System.out.println(author.getName()));
}
// 2.数组流
private static void test02() {Integer[] arr = {1,2,3,4,5};
//  IntStream stream = Arrays.stream(arr);Stream<Integer> stream = Stream.of(arr);stream.distinct().filter(value -> value > 2).forEach(value -> System.out.println(value));
}
// 3.双列集合   map流
private static void test03() {Map<String, Integer> map = new HashMap<>();map.put("张三", 18);map.put("李四", 33);map.put("王五", 25);Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();stream.filter(entry -> entry.getValue()>20).forEach(entry -> System.out.println(entry.getKey()));
}

中间操作

  • filter 对流中的操作进行过滤,符合条件的返回
    使用的函数式接口是:Predicate,参数是一个实体,拥有抽象方法:boolean test(T t);
authors.stream().filter(new Predicate<Author>() {@Override// 匿名内部类的test方法,将传入的author进行判断,返回符合条件的public boolean test(Author author) {return author.getName().length() > 1;}
}).forEach(author -> System.out.println(author.getName()));

该操作将作者名字长度>1 的作者名列出来

  • map 把流中元素进行计算或转换
    使用的函数式接口是:Function<T, R>,参数是一个实体,和一个要将实体转化的结果result,拥有抽象方法:R apply(T t);
    (1)进行转换,该操作将作者名字列出来
private static void test05(List<Author> authors) {authors.stream().map(new Function<Author, String>() {@Override// 匿名内部类的apply方法,将传入的author进行需要的结果返回public String apply(Author author) {return author.getName();}}).forEach(s -> System.out.println(s));
}

(2)进行计算,该操作将作者年龄分别+10

authors.stream().map(author -> author.getAge()).map(new Function<Integer, Integer>() {@Overridepublic Integer apply(Integer age) {return age + 10;}}).forEach(s -> System.out.println(s));

第一个map是获取作者的年龄,然后第二个map则将年龄转换为年龄,只是经过了+10计算,我们打断点看看
在这里插入图片描述
流经过第一个map后转换为了Integer
在这里插入图片描述
经过第二个map后将第一个Integer进行+10计算,类型不变

  • distinct 将元素进行去重操作
    注意:distinct 依赖Object 的equals方法来判断对象是否相同,对象要重写equals方法。
authors.stream().distinct().forEach(author -> { System.out.println(author.getName()); });

该操作直接通过distinct去重
当然也可以使用前面的map提取出名字,再去重,比上面的麻烦些

authors.stream().distinct().map(new Function<Author, String>() {@Overridepublic String apply(Author author) {return author.getName();}}).forEach(name -> { System.out.println(name); });// 一样
authors.stream().distinct().map(author -> author.getName()).forEach(name -> { System.out.println(name); });

该操作先使用map将Author对象转换为姓名的String,然后在去重

  • flatMap
    上面的Map是把一个对象转换成另一个对象作为流中的元素,而flatMap是把一个对象转换为多个对象作为流中的元素

使用的函数式接口是:new Function<T, R>,将一个对象转换成Stream对象

(1)打印所有书籍的名字,要求对重复的元素进行去重。

authors.stream().flatMap(new Function<Author, Stream<Book>>() {// 这里可以通过idea进行lambda转换,为了清晰就不转了@Overridepublic Stream<Book> apply(Author author) {return author.getBooks().stream();}}).distinct().forEach(name -> { System.out.println(name); });

如果使用Map,将作者对象提取出书籍对象,还需要再对书籍对象List进行遍历去重,比较麻烦。
首先使用flatMap将每个作者对象中的书籍对象流提取出来,然后直接在书籍对象流中进行去重,输出书籍名称。
在这里插入图片描述
在这里插入图片描述
(2)打印现有数据的所有分类,要求对分类进行去重,不能出现这种格式:哲学,爱情,需要转成两个分类

authors.stream().flatMap(author -> author.getBooks().stream()).distinct()// 将分类进行分割成数组后,转成流进行去重.flatMap(book -> Arrays.stream(book.getCategory().split(","))).distinct().forEach(category -> System.out.println(category));

在这里插入图片描述
第一次使用flatmap将作者对象转换成多个书籍对象流
在这里插入图片描述

第二次使用flatmap将书籍对象的分类转换成多个分类流

终结操作

  • forEach 对流中元素进行遍历操作
  • count 获取当前流中元素的个数
    (1)打印这些作家所出书籍的数目,注意删除重复元素
    因为count属于终结操作,会有返回值
long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();
System.out.println("书籍count = " + count);

在这里插入图片描述
使用flatMap获取每个书籍对象,去重计算
在这里插入图片描述

  • min和max 求流中的最值
    (1)获取这些作家的所出书籍的最高分和最低分
Optional<Integer> max = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).max(new Comparator<Integer>() {@Overridepublic int compare(Integer score1, Integer score2) {return score1 - score2;}});
System.out.println("书籍评分max = " + max.get());Optional<Integer> min = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).min(new Comparator<Integer>() {@Overridepublic int compare(Integer score1, Integer score2) {return score1 - score2;}});
System.out.println("书籍评分min = " + min .get());

先使用flatMap将作者对象转换成多个书籍对象流,然后用map获取书籍对象中的评分对象,进行max和min计算

  • collect 把当前流转换成一个集合
    (1)获取一个存放所有作者名字的List集合
List<String> list = authors.stream().map(author -> author.getName()).distinct().collect(Collectors.toList());System.out.println("list = " + list);

(2)获取一个所有书名的set集合

Set<String> set = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getName()).collect(Collectors.toSet());System.out.println("set = " + set);

(3)获取一个map集合,key为作者名,value为List

Map<String, List<Book>> map = authors.stream()// 去重避免key重复.distinct().collect(Collectors.toMap(new Function<Author, String>() {@Override // 这里的匿名内部类将传入作者对象,获取作者名作为keypublic String apply(Author author) { return author.getName(); }}, new Function<Author, List<Book>>() {@Override // 这里的匿名内部类将传入作者对象,获取书籍list作为valuepublic List<Book> apply(Author author) { return author.getBooks(); }}));System.out.println("map = " + map);

简化lambda表达式

Map<String, List<Book>> map = authors.stream()// 去重避免key重复.distinct().collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));System.out.println("map = " + map);
  • anyMatch 判断流中是否有任意符合匹配条件的元素,符合返回true
boolean b = authors.stream().anyMatch(author -> author.getAge() > 29);System.out.println("b = " + b);

判断是否有年龄在29以上的作家

  • allMatch 判断流中元素是否都符合条件,都符合为true,否则为false
boolean b = authors.stream().allMatch(author -> author.getAge() >= 18);
System.out.println("b = " + b);

判断是否所有作家都是成年人

  • noneMatch 判断流中元素是否都不符合条件,是为true,否为false
boolean b = authors.stream().noneMatch(author -> author.getAge() > 100);
System.out.println("b = " + b);

判断作家是否都没有超过100岁的

  • findAny 获取流中符合条件的任意一个元素,不保证为流中的第一个元素
Optional<Author> au = authors.stream().filter(author -> author.getAge() > 18).findAny();System.out.println("名字:" + au.get().getName());

这里用的get方法获取数据,但是可能出现找不到符合条件的数据,这时候get就会报错,如:
在这里插入图片描述
所以改成:

Optional<Author> au = authors.stream().filter(author -> author.getAge() > 98).findAny();au.ifPresent(author -> System.out.println(author.getName()));

获取任意一个大于18的作家,输出名字

  • findFirst 获取流中的第一个元素
Optional<Author> author = authors.stream().sorted((o1, o2) -> o1.getAge() - o2.getAge()).findFirst();author.ifPresent(author1 -> System.out.println(author1.getName()));

获取年龄最小的作家,输出名字

  • reduce归并 对流中的数据按照指定的计算方式计算出一个结果(缩减操作)
    把stream中的元素组合起来,传入初始化值,按照指定的计算方式和元素进行计算,计算结果再和下一个元素进行计算,依次计算完

reduce有三种重载方式

  1. 2个参数的
    T reduce(T identity, BinaryOperator accumulator);
T result = identity;
for (T element : this stream) {result = accumulator.apply(result, element)
}
return result;

传入初始化值作为第一个参数identity,传入计算方法accumulator.apply 进行初始化值和元素的计算

例子:
(1)使用reduce对作者年龄进行求和

Integer result = authors.stream().distinct().map(author -> author.getAge())// 传入初识值和计算方法.reduce(0, new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer result, Integer element) {return result + element;}});System.out.println("result = " + result);

lambda写

Integer result = authors.stream().distinct().map(author -> author.getAge())// 传入初识值和计算方法.reduce(0, (result1, element) -> result1 + element);System.out.println("result = " + result);

(2)使用reduce求所有作者年龄最大值

Integer max = authors.stream().distinct().map(author -> author.getAge()).reduce(Integer.MIN_VALUE, new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer result, Integer element) {return result > element ? result : element;}});
System.out.println("max = " + max);

(3)使用reduce求所有作者年龄最小值

Integer min = authors.stream().distinct().map(author -> author.getAge()).reduce(Integer.MAX_VALUE, new BinaryOperator<Integer>() {@Overridepublic Integer apply(Integer result, Integer element) {return result > element ? element : result;}});System.out.println("min = " + min);
  1. 1个参数的
    Optional reduce(BinaryOperator accumulator);
boolean foundAny = false;
T result = null;
for (T element : this stream) {if (!foundAny) {foundAny = true;result = element;} else {result = accumulator.apply(result, element);}
}return foundAny ? Optional.of(result) : Optional.empty();

该方法只传入了一个计算方式,根据实现方法,可以看到将流中的第一个元素作为了第一个元素result,然后后续进行else内部的计算

例如:

Optional<Integer> optional = authors.stream().distinct().map(author -> author.getAge())// 直接传入计算方法.reduce((result, element) -> result > element ? element : result);optional.ifPresent(integer -> System.out.println(integer));

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

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

相关文章

解锁文档处理新境界:ONLYOFFICE编辑功能为开发者带来新机遇

引言 ONLYOFFICE最新发布的文档8.0版本带来了一系列引人注目的功能和优化&#xff0c;为用户提供了更强大、更高效的在线编辑体验。这次更新涵盖了多个方面&#xff0c;包括PDF表单、RTL支持、单变量求解、图表向导以及插件界面设计更新等。这些新功能不仅提升了文档处理的便利…

职业资格高级执法考试试题及答案,分享几个实用搜题和学习工具 #知识分享#微信

作为当代大学生&#xff0c;我们常常面临着繁重的学业压力和众多的学习任务。在这个信息爆炸的时代&#xff0c;如何高效地进行搜题和学习成了我们迫切需要解决的问题。幸运的是&#xff0c;随着科技的不断进步&#xff0c;我们拥有了许多方便、实用的日常搜题和学习软件。 1.…

旗舰配置,巅峰性能 | 一文玩转铁威马 『F4-424 Pro』强大的Docker虚拟机功能【附产品开箱】

旗舰配置&#xff0c;巅峰性能 | 一文玩转铁威马 『F4-424 Pro』强大的Docker&虚拟机功能【附产品开箱】 哈喽小伙伴们&#xff0c;我是Stark-C~ 开篇 记得还在两个月之前&#xff0c;我为大家介绍了国产“开箱即用”的国民专业级NAS『铁威马』&#xff1a; &#x1f53…

idea代码review工具Code Review Helper使用介绍

之前在团队里面遇到一个关于代码review的问题&#xff0c;使用gitlab自己的还是facebook的Phabricator&#xff0c;很难看到整体逻辑&#xff0c;因为业务逻辑代码可能不在这次改动范围内&#xff0c;在去源库中找不好找。针对这个刚需&#xff0c;在网上找了一个idea的代码工具…

kali安装awvs报错error creating the database

修改host文件 vim /etc/hosts 加入 127.0.0.1 kali 重启再安装即可解决

软件实例分享,操作简单美发店会员登记记账本vip会员管理系统软件教程

软件实例分享&#xff0c;操作简单美发店会员登记记账本vip会员管理系统软件教程 一、前言 以下软件程序教程以 佳易王美发店会员管理系统软件V16为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、新会员可以直接使用手.机号&#xff0c;不需…

Kernelized Correlation Filters KCF算法原理详解(阅读笔记)(待补充)

KCF 目录 KCF预备知识1. 岭回归2. 循环移位和循环矩阵3. 傅里叶对角化4. 方向梯度直方图&#xff08;HOG&#xff09; 正文1. 线性回归1.1. 岭回归1.2. 基于循环矩阵获取正负样本1.3. 基于傅里叶对角化的求解 2. 使用非线性回归对模型进行训练2.1. 应用kernel-trick的非线性模型…

如何使用IP代理解决亚马逊账号IP关联问题?

亚马逊账号IP关联问题是指当同一个IP地址下有多个亚马逊账号进行活动时&#xff0c;亚马逊会将它们关联在一起&#xff0c;从而可能导致账号被封禁或限制。 为了避免这种情况&#xff0c;许多人选择使用IP代理。 IP代理为什么可以解决亚马逊IP关联问题&#xff1f; IP代理是…

欲速则不达,慢就是快!

引言 随着生活水平的提高&#xff0c;不少人的目标从原先的解决温饱转变为追求内心充实&#xff0c;但由于现在的时间过得越来越快以及其他外部因素&#xff0c;我们对很多东西的获取越来越没耐心&#xff0c;例如书店经常会看到《7天精通Java》、《3天掌握XXX》等等之类的书籍…

金山下的wps,无法删除水印

RT&#xff0c;正常删除水印的流程是&#xff0c;插入-水印-删除水印。 如图的操作方法不生效时&#xff0c;可用下面的方法 点击页眉或页脚&#xff0c;进入页眉的编辑模式&#xff0c;可以看到水印变成可以选中的状态&#xff0c;选中&#xff0c;点击delete或者鼠标右键删…

如何使用Docker搭建YesPlayMusic网易云音乐播放器并发布至公网访问

文章目录 1. 安装Docker2. 本地安装部署YesPlayMusic3. 安装cpolar内网穿透4. 固定YesPlayMusic公网地址 本篇文章讲解如何使用Docker搭建YesPlayMusic网易云音乐播放器&#xff0c;并且结合cpolar内网穿透实现公网访问音乐播放器。 YesPlayMusic是一款优秀的个人音乐播放器&am…

知识蒸馏实战代码教学一(原理部分)

一、知识蒸馏的来源 知识蒸馏&#xff08;Knowledge Distillation&#xff09;源自于一篇由Hinton等人于2015年提出的论文《Distilling the Knowledge in a Neural Network》。这个方法旨在将一个大型、复杂的模型的知识&#xff08;通常称为教师模型&#xff09;转移到一个小型…

[Bug解决] Invalid bound statement (not found)出现原因和解决方法

1、问题描述 在写了一个很普通的查询语句之后&#xff0c;出现了下面的报错信息 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.xxx.oauth.mapper.WxVisitorQrBeanMapper.selectByComIdAndEmpId at org.apache.ibatis.binding.Mappe…

嵌入式C语言学习——基于Linux与GCC(二)

系列文章目录 一.C语言常用关键字及运算符操作 文章目录 系列文章目录内存四区指针指针概述指针 修饰符constvolatiletypedef 指针运算符多级指针 数组数组空间字符空间及地址 结构体、共用体定义、字节对齐位域 内存分布图段错误分析 内存四区 C/C语言的内存四区&#xff0…

Django模板(四)

一、include标签 加载一个模板,并在当前上下文中进行渲染。这是一种在模板中 “包含” 其他模板的方式 简单的理解:在当前模板中引入另外一个模板内容 1.1、使用方法 模板名称可以是变量,也可以是单引号或双引号的硬编码(带引号)的字符串 {% include "foo/bar.ht…

ALBEF算法解读

ALBEF论文全名Align before Fuse: Vision and Language Representation Learning with Momentum Distillation&#xff0c;来自于Align before Fuse&#xff0c;作者团队为Salesforce Research。 论文地址&#xff1a;https://arxiv.org/pdf/2107.07651.pdf 论文代码&#xff1…

美国首届生成式人工智能与法律研讨(上)

美国首届生成式人工智能与法律研讨(上) 文章目录 美国首届生成式人工智能与法律研讨(上)前言一、引言二、生成式AI对法律的影响三、生成式AI与法律的跨学科研究3.1 确定和定义跨学科术语3.2 构建有价值的隐喻3.3 理解不断发展的商业模式四、生成式AI的独特性4.1 从执行狭义…

[OpenAI]继ChatGPT后发布的Sora模型解析与体验通道

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言OpenAI体验通道Spacetime Latent Patches 潜变量时空碎片, 建构视觉语言系统…

【RHCE】shell条件测试练习

目录 1、判断当前磁盘剩余空间是否有20G&#xff0c;如果小于20G&#xff0c;则将报警邮件发送给管理员&#xff0c;每天检查次磁盘剩余空间。 2、判断web服务是否运行 3、使用curl命令访问第二题的web服务&#xff0c;看能否正常访问&#xff0c;如果能正常访问&#xff0c;…

《戴森球计划》好玩吗?《戴森球计划》怎么在苹果电脑上安装 戴森球计划攻略 Mac游戏推荐

《戴森球计划》是一款具有强大现实科学基础的模拟策略游戏&#xff0c;玩家的目标是构建能源效率极高的戴森球以解决能源问题。游戏的背景设定启发于科幻作品中的戴森球概念。游戏采用逼真的物理模拟&#xff0c;玩家需要合理规划资源&#xff0c;以应对复杂的能源危机。那么《…