IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Stream流粗解 -> 正文阅读

[开发测试]Stream流粗解

Stream流粗解

  • 声明性——更简洁,更易读
  • 可复合——更灵活
  • 可并行——性能更好

案例传送门:Stream流使用案例

  • 通过对交易的各项业务查询熟悉流的使用
Map<Dish.Type, List<Dish>> dishesByType = menu.stream().collection(groupingBy(Dish::getType));

流简介

简短定义:从支持数据处理操作的源生成的元素序列。

  • 元素序列:类似于集合,流也提供了一个接口,可以访问特定元素类型的一组有序值。与集合不同,集合的主要目的是以特定的时间和空间复杂度存储和访问元素(如ArrayList和LinkedList)。流的主要目的在于表达计算。集合讲的是数据,流讲的是计算。
  • 源: 流会使用一个提供数据的源,如集合、数组或输入/输出资源。从有序集合生成流时会保留原有的顺序。由列表生成的流,其元素顺序与列表一致。
  • 数据处理操作:流的数据处理功能类似于数据库的操作,以及函数式编程语言的常用操作,如filter、map、reduce、find、match、sort等。流操作可以顺序执行,也可以并行执行
  • 流水线:很多流操作本身会返回一个流,所以多个操作就可以链起来,形成一个流水线。
  • 内部迭代:与使用迭代器显式迭代的集合不同,流的迭代操作是在背后进行的。

示例如下,结果为:[pork, beef, chicken]

List<String> threeHighCalorDishNames 
					= menu.stream() //源为menu,是一个列表,在Stream流案例中的Dish类可以看到定义
						  /**
						   * Stream<T> filter(Predicate<? super T> predicate),steam流可用的一个操作,接收一个Predicate接口对象
						   * boolean test(T t),Predicate函数式接口定义的抽象方法,签名为 T -> booean
						   * 经过filter操作(筛选卡路里高于300的)得到新流
						   */
						  .filter(d -> d.getCalories() > 300) 
						  /**
						   * <R> Stream<R> map(Function<? super T, ? extends R> mapper),steam流可用的一个操作,接收一个Function接口对象
						   * R apply(T t),Function函数式接口定义的抽象方法,签名为 T -> R
						   * 经过map操作(映射为菜名)得到新流
						   */
						  .map(Dish::getName)
						  /**
						   * Stream<T> limit(long maxSize),steam流可用的一个操作,接收一个long型整数
						   * 经过limit操作(只选择前三个)得到新流
						   */
						  .limit(3)
						  /**
						   * 返回一个list
						   */
						  .collect(Collectors.toList());

System.out.println(threeHighCalorDishNames);

流与集合

集合:是一个内存中的数据结构,它包含数据结构中目前所有的值——集合中的每个元素都得先算出来才能添加到集合中。

  • 可比喻为DVD,视频已经完全存储到了DVD中。

流:是在概念上固定的数据结构(不能添加或删除元素),其元素时按需计算的,就像一个延迟创建的集合:在按需的一步步操作完成后才创建集合。

  • 可比喻为在线流媒体,缓存一部分看一部分,按需操作。
  • 也可比喻为用浏览器进行互联网搜索,假设搜索到多条匹配项,而可以得到一个流仅展示10个,点击下一页可展示接下来的10个,每次请求都是10个。

只能遍历一次

和迭代器类似,流只能遍历一次。遍历完成后,就称这个流已经被消费掉了。如下代码:

List<String> title = Arrays.asList("Java8", "Lambda", "Steam");
Stream<String> s = title.stream();
/**
 * Stream: void forEach(Consumer<? super T> action);
 * Consumer: void accept(T t);
 */
s.forEach(System.out::println);
s.forEach(System.out::println);

结果如图:只会遍历一次,第二次遍历就抛出了异常,说明流已经被消费掉了。
在这里插入图片描述

外部迭代与内部迭代

使用Collection接口需要用户去做迭代(比如for-each),这称为外部迭代。相反,Streams库使用内部迭代——它帮你把迭代做了,还把得到的流存在了某个地方,只需要给出函数说要干什么就可以了。如下分别是集合和流的代码,说明了这种区别。

  • 集合:用for-each循环外部迭代
List<String> names = new ArrayList<>();
for (Dish d : menu) { // 显示顺序迭代菜单列表
	names.add(d.getName()); // 提取名称并将其添加到累加器
}
  • 集合:用背后的迭代器做外部迭代
List<String> names = new ArrayList<>();
Iterator<Dish> iterator = menu.iterator();
while (iterator.hasNext()) {
    Dish d = iterator.next();
    names.add(d.getName());
}
  • 流:内部迭代
List<String> names = menu.stream()
                .map(Dish::getName) // 传递行为,用getName方法参数化map,提取菜名
                .collect(Collectors.toList());
集合:外部迭代,必须一个一个处理

你:“索菲亚,我们把玩具收起来吧。地上还有玩具吗?”
索菲亚:“有,球。”
你:“好,把球放进盒子里。还有吗?”
索菲亚:“有,娃娃。”
你:“好,把娃娃放进盒子里。还有吗?”

索菲亚:“没了,没有了。”
你:“好,我们收完了。”

流:内部迭代,可以很好的并行处理,索菲亚可以一手球一手娃娃

你:“索菲亚,把地上的玩具都收起来。”
索菲亚:“好的。”

流操作

  • 中间操作:从源获取流开始,可以进行多个类似于filter、sorted方法等中间操作,这些操作的结果还是流。
  • 终端操作:经过一系列的中间操作后,最后使用一个终端方法,从流的流水线生成结果,该结果为其他非流的值,如List、Integer等,甚至可以是void。
  • 使用流:
    • 一个数据源(如集合)来执行一个查询;
    • 一个中间操作链,形成一条流的流水线;
    • 一个终端操作,执行流水线,并能生成结果。

使用流,具体案例点此

筛选和切片

filter

Stream接口支持filter方法,该操作接受一个谓词作为参数,并返回一个包含符合谓词的元素的流。

List<Dish> vegetarianMenu = menu.stream()
								.filter(Dish::isVegetarian)
								.collect(toList());
distinct

Stream接口支持distinct方法,该操作会返回一个元素各异的流。

List<Integer> numbers = Arrays.asList(1,2,1,3,3,2,4);
numbers.stream()
	   .filter(i -> i % 2 == 0)
	   .distinct()
	   .forEach(System.out::println);
limit

Stream接口支持limit(n)方法,该方法返回一个不超过给定长度的流。

List<Dish> dishes = menu.stream()
						.filter(d -> d.getCalories() > 300)
						.limit(3)
						.collect(toList());
skip

Stream接口支持skip(n)方法,与limit方法互补,返回一个丢掉前n元素的流。

List<Dish> dishes = menu.stream()
						.filter(d -> d.getCalories() > 300)	
						.skip(2)
						.collect(toList());	

映射

Stream接口支持map和flatMap方法,接收一个函数作为参数,这个函数会作用到流的每个元素,并将其映射成一个新的元素。

map
flatMap

查找和匹配

anyMatch
allMatch
findAny
findFirst

规约

reduce
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:55:28  更:2022-03-30 18:56:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:15:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码