Stream流学习笔记

Stream流

    • 创建流
    • 中间操作
      • 1、filter
      • 2、map
      • 3、distinct
      • 4、sorted
      • 5、limit
      • 6、skip
      • 7、flatMap
    • 终结操作
      • 1、forEach
      • 2、count
      • 3、max&min
      • 4、collect
      • 5、查找与匹配

创建流

单例集合:集合对象.stream()

List<Integer> list = new ArrayList<>();
Stream<Integer> stream = list.stream();

数组:Arrays.stream(数组) 或 Stream.of(数组) 来创建

Integer[] arr = {1,2,3,4};
Stream<Integer> stream1 = Arrays.stream(arr);
Stream<Integer> stream2 = Stream.of(arr);

双例集合:转换成单例集合后再创建

Map<String, String> map = new HashMap<>();
Stream<Map.Entry<String, String>> stream3 = map.entrySet().stream();

中间操作

1、filter

对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。

public static void test() {List<Author> authors = getAuthors();authors.stream().filter(author -> author.getAge() > 18) //中间操作.forEach(author -> System.out.println(author)); //终结操作
}

2、map

可以把流中的元素进行计算或转换。

转换:

public static void test() {List<Author> authors = getAuthors();//泛型中,第一个参数为方法的参数类型,第二个参数为方法的返回值类型authors.stream().map(author -> author.getName()).forEach(name -> System.out.println(name));
}

3、distinct

去除流中的重复元素。

注意:distinct方法是依赖Object的equals方法来判断是否是相同对象,所以需要重写equals方法。

4、sorted

对流中的元素进行排序。

方式一:调用sorted()空参方法
在比较的实体类上要实现Comparable接口,不然会报类型不匹配的异常。

image-20240212122159278

public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted().forEach(author -> System.out.println(author.getAge()));
}

方式二:在sorted方法中实现Comparator接口

public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted(new Comparator<Author>() {@Overridepublic int compare(Author o1, Author o2) {return o1.getAge()-o2.getAge();}}).forEach(author -> System.out.println(author.getAge()));
}

优化

public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted((o1, o2) -> o1.getAge()-o2.getAge()).forEach(author -> System.out.println(author.getAge()));
}

5、limit

可以设置流的最大长度,超出的部分将被抛弃。

//对流中的元素按照年龄进行降序排序,并且要求不能有重复元素,打印其中年龄最大的两个作家。
public static void test2() {List<Author> authors = getAuthors();authors.stream().distinct().sorted((o1, o2) -> o2.getAge()-o1.getAge()).limit(2).forEach(author -> System.out.println(author.getName()));
}

6、skip

跳过流中的前n个元素,返回剩下的元素。

7、flatMap

map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素。

案例1:打印所有书籍的名字,要求对重复的元素进行去重。
map方式:Author对象的books属性是集合类型,使用原来map转换对象,要使用嵌套循环进行打印。

public static void test2() {List<Author> authors = getAuthors();authors.stream().map(author -> author.getBooks()).forEach(books -> {for (Book book : books) {System.out.println(book.getName());}});
}

flatMap方式:

public static void test2() {List<Author> authors = getAuthors();authors.stream().flatMap(author -> author.getBooks().stream()).forEach(book -> System.out.println(book.getName()));
}

案例二:打印现有数据的所有分类,要求对分类进行去重。不能出现这种格式:哲学,爱情,要将它们拆开输出。

public static void test3() {List<Author> authors = getAuthors();authors.stream().flatMap(author -> author.getBooks().stream()).distinct().flatMap(book -> Arrays.stream(book.getCategory().split(","))).distinct().forEach(category -> System.out.println(category));
}

终结操作

1、forEach

对流中的元素进行遍历操作,我们通过传入的参数去指定对遍历到的元素进行什么具体操作。

2、count

获取当前流中元素的个数。

//打印这些作家的所出书籍的数量
public static void test4() {List<Author> authors = getAuthors();long count = authors.stream().flatMap(author -> author.getBooks().stream()).distinct().count();System.out.println(count);
}

3、max&min

获取流中的最值

//分别获取这些作家所出书籍的最高分和最低分
public static void test4() {List<Author> authors = getAuthors();Optional<Integer> max = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).max((o1, o2) -> o1 - o2);Optional<Integer> min = authors.stream().flatMap(author -> author.getBooks().stream()).map(book -> book.getScore()).min(((o1, o2) -> o1 - o2));System.out.println(max.get());System.out.println(min.get());
}

4、collect

把当前流转换成一个集合。

list集合

//获取一个存放所有作者名字的list集合
public static void test5() {List<Author> authors = getAuthors();List<String> nameList = authors.stream().map(author -> author.getName()).collect(Collectors.toList());System.out.println(nameList);
}

set集合

//获取一个存放所有作者名字的set集合
public static void test5() {List<Author> authors = getAuthors();Set<String> nameList = authors.stream().map(author -> author.getName()).collect(Collectors.toSet());System.out.println(nameList);
}

map集合

//获取一个Map集合,map的key为作者名,value为List<Book>
public static void test5() {List<Author> authors = getAuthors();Map<String, List<Book>> map = authors.stream().distinct().collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));System.out.println(map);
}

5、查找与匹配

(1)anyMatch:判断是否有任意符合匹配条件的元素,结果为boolean类型。

//判断是否有作家年龄在18以上
public static void test6() {List<Author> authors = getAuthors();boolean flag = authors.stream().anyMatch(author -> author.getAge() > 18);System.out.println(flag);
}

(2)allMatch:判断是否都符合条件,如果都符合返回true,否则返回false

//判断是否所有作家年龄在18以上
public static void test6() {List<Author> authors = getAuthors();boolean flag = authors.stream().allMatch(author -> author.getAge() > 18);System.out.println(flag);
}

(3)noneMatch:判断流中的元素是否都不符合匹配条件,如果都不符合结果为true,否则结果为false。

(4)findAny:获取流中的任意一个元素。该方法没有办法保证获取到的一定是流中的第一个元素。

//获取任意一个年龄大于18的作家,如果存在就输出他的名字
public static void test7() {List<Author> authors = getAuthors();Optional<Author> any = authors.stream().filter(author -> author.getAge() > 18).findAny();//如果这个Optional中有元素,则执行方法,没有就不执行any.ifPresent(author -> System.out.println(author.getName()));
}

(5)findFirst:获取流中的第一个元素。

//获取一个年龄最小的作家,并输出他的姓名
public static void test7() {List<Author> authors = getAuthors();Optional<Author> any = authors.stream().sorted((o1, o2) -> o1.getAge()-o2.getAge()).findFirst();any.ifPresent(author -> System.out.println(author.getName()));
}

(6)reduce归并
对流中的数据按照你指定的计算方式计算出一个结果。(缩减操作)

reduce的作用是把stream中的元素给组合起来。我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和初始化值进行计算,计算结果再和后面的元素计算。

它内部的计算方式如下:

T result = identity;
for (T element : this stream)result = accumulator.apply(result, element)
return result;

其中identity就是我们可以通过方法参数传入的初始值,accumulator的apply具体进行什么计算也是我们通过方法参数来确定的。

案例1:使用reduce求所有作者年龄的和

public static void test8() {List<Author> authors = getAuthors();Integer sum = authors.stream().distinct().map(author -> author.getAge())//初始值为0,后面 result+=element,最后 return result.reduce(0, (result, element) -> result + element);System.out.println(sum);
}

案例2:使用reduce求所有作者中年龄的最大值

public static void test8() {List<Author> authors = getAuthors();Integer max = authors.stream().map(author -> author.getAge()).reduce(Integer.MIN_VALUE, (result, element) -> result > element ? result : element);System.out.println(max);
}

reduce有个重载形式,内部代码如下:

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();

利用这个重载形式,求作者年龄的最大值,不用传递初始值了。

public static void test8() {List<Author> authors = getAuthors();Optional<Integer> max = authors.stream().map(author -> author.getAge()).reduce((result, element) -> result > element ? result : element);System.out.println(max.get());
}

注意事项
惰性求值:如果没有终结操作,中间操作是不会得到执行的。

流是一次性的:一旦一个流对象经过一个终结操作后,这个流就不能再被使用了,只能重新创建流对象再使用。

不会影响原数据:我们在流中可以对数据做很多处理,但正常情况下是不会影响原来集合中的元素的。

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

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

相关文章

uniapp禁止截屏录屏/投屏功能(adb投放失效)

经过测试代码写在App.vue会失效,请写在符合逻辑的界面 uni-app 实现安卓防截屏 在uniapp中实现 要在App中全局禁止截屏&#xff0c;那么可以在App.vue中调用 如果想要某个页面防截屏就在某个页面调用&#xff0c;但是在离开这个页面的时候要恢复截屏&#xff0c;否则全局…

C语言:详解操作符(下)

上一篇链接&#xff1a;C语言&#xff1a;详解操作符&#xff08;上&#xff09;摘要&#xff1a; 在上篇文章中&#xff0c;我们已经讲过位操作符等涉及二进制的操作符&#xff0c;这些有助于帮助我们后期理解数据如何在计算机中运算并存储&#xff0c;接下来本篇将更多的讲述…

OpenCV学习路线图

下面是针对初学者设计的一个学习路线图&#xff1a; 第1周&#xff1a;计算机视觉和OpenCV概述 介绍计算机视觉及其应用领域讨论OpenCV的历史、特点和工作原理OpenCV的安装和配置&#xff08;Windows/Linux/macOS&#xff09;了解OpenCV的基本数据结构&#xff08;cv::Mat等&…

如何清理Docker占用的磁盘空间?

在Docker中&#xff0c;随着时间的推移&#xff0c;占用的磁盘空间可能会不断增加。为了保持系统的稳定性和性能&#xff0c;定期清理Docker占用的磁盘空间非常重要。下面将介绍一些清理Docker磁盘空间的方法。 一、清理无用的容器 有时候&#xff0c;我们可能会运行一些临时…

mac docker 宿主机和容器间网络打通

动因 是这样&#xff0c;笔者最近满怀欣喜入手Docker&#xff0c;看着各种文章命令都是不断点头称道&#xff1a;“嗯嗯&#xff0c;不错不错”,在接下来终于准备大干一场的时候碰壁了&#xff0c;主要情况是说在Mac中跑了第一把的时候发现碰到&#xff0c;虚拟机和宿主机居然…

Vue-1

Vue 简介 Vue 是一个用于"构建用户界面(基于数据渲染出用户看到的画面)" 的渐进式框架 基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widt…

SpringBoot 2.7.6 集成Activiti 7.1.0.M6 所需的配置文件

<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 https://…

课时25:内容格式化_常用符号解读_信息传递

3.1.1 信息传递 学习目标 这一节&#xff0c;我们从 重定向、管道符、小结 三个方面来学习。 重定向 重定向符号 在shell脚本中有两类常见的重定向符号&#xff1a; 覆盖式重定向&#xff1a;> 表示将符号左侧的内容&#xff0c;以覆盖的方式输入到右侧文件中< 表示…

c# avalonia 实现正方体翻转效果

在Avalonia中要实现一个正方体的翻转效果&#xff0c;需要利用动画和变换的功能&#xff0c;但由于Avalonia主要是2D UI框架&#xff0c;对3D支持有限。你可以通过2D的方式来近似模拟3D翻转的效果&#xff0c;或者配合像Avalonia3D这样的扩展库来实现。 示例代码大纲如下&#…

C#系列-C#访问WebAPI(11)

在C#中访问Web API通常涉及使用HttpClient类来发送HTTP请求到Web服务器并接收响应。以下是一个简单的示例&#xff0c;展示了如何使用HttpClient来调用一个Web API并获取JSON响应。 首先&#xff0c;确保你的项目中包含了System.Net.Http命名空间。如果你使用的是.NET Core或.…

CentOS7下如何安装Nginx

一、Ngxin是什么 Nginx是一个开源的 Web 服务器&#xff0c;具有反向代理、负载均衡、缓存等功能。它可以作为 HTTP 服务器&#xff0c;将服务器上的静态文件&#xff08;如 HTML、图片&#xff09;通过 HTTP 协议展现给客户端&#xff0c;也可以实现动静分离&#xff0c;把动态…

【后端高频面试题--Nginx篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 后端高频面试题--Nginx篇 什么是Nginx&#xff1f;为什么要用Nginx&#xff1f;为什么Nginx性能…

如何查看电脑连接的wifi的密码

问题 很多时候我们电脑连上wifi之后就把密码忘记了&#xff0c;这个时候如果同事问自己密码是多少&#xff0c;如果作为程序员说不知道是不是感觉有点不好意思&#xff0c;哈哈…… 解决 我使用的是windows电脑&#xff0c;就以windows为例说明下自己是如何查看的。 打开wi…

SNMP(简单网络管理协议)介绍

简介 作为系统管理员的重要工作之一是收集关于服务器和基础设施的准确信息。有许多工具和选项可用于收集和处理这种类型的信息。其中许多工具都是建立在一种称为SNMP的技术之上。 SNMP代表简单网络管理协议。这是服务器可以共享有关其当前状态的信息的一种方式&#xff0c;也…

c# Avalonia 伪类 Pseudo Classes 改变样式

在Avalonia UI框架中&#xff0c;伪类是一种选择器&#xff0c;它们用于在XAML样式中更改控件的视觉状态&#xff0c;而不更改其逻辑状态。伪类经常用于描述控件的特定状态&#xff0c;如激活、禁用、焦点等&#xff0c;并且可以根据这些状态应用不同的样式规则。 使用伪类时&a…

学习数据结构和算法的第7天

线性表 **线性表(linear list&#xff09;&#xff1a;**是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一条直…

FAST角点检测算法

FAST&#xff08;Features from Accelerated Segment Test&#xff09;角点检测算法是一种快速且高效的角点检测方法。它通过检测每个像素周围的连续像素集合&#xff0c;确定是否为角点。以下是 FAST 角点检测算法的基本流程&#xff1a; FAST 角点检测算法的基本过程主要包括…

2024年华为OD机试真题-测试用例执行计划-Python-OD统一考试(C卷)

题目描述: 某个产品当前迭代周期内有N个特性( F1,F2,.......FN)需要进行覆盖测试,每个特性都被评估了对应的优先级,特性使用其ID作为下标进行标识。 设计了M个测试用例(T1,T2......,TM ),每个用例对应了一个覆盖特性的集合,测试用例使用其ID作为下标进行标识,测试用例…

Dubbo集成Zookeeper embbed模式

为了简化应用支持服务方便的分合&#xff0c;使用Zookeeper embbed模式。集成Zookeeper比较容易&#xff0c;使用starter或自己写代码都可以。但是由于集成了Dubbo&#xff0c;每次启动时都会发现zookeeper没有启动就开始报错退出&#xff0c;但是确是已经集成了。 于是只能翻…

精读《Web Components 的困境》

本期精读的文章是&#xff1a;The broken promise of Web Components 以及对这篇文章的回应: Regarding the broken promise of Web Components 1 引言 我为什么要选这篇文章呢&#xff1f; 就在前几天的 Google I/O 2017 上, Polymer 正式发布了 Polymer 2.0 版本. 来看…