Stream学习:StreamAPI详解

Java8新特性



前言

Java8之前的集合操作不能满足需求的快速发展。所以Steam应运而生。

Stream是对容器对象功能的增强,专注于对容器对象进行各种便利、高效的聚合操作(aggregate operation)或者大批量数据操作。

它提供串行和并行两种模式进行汇聚操作。

stream是一个函数式语言+多核时代综合影响的产物。

清单 2. Java 8 的排序、取值实现

List<Integer> transactionsIds = transactions.parallelStream().
 filter(t -> t.getType() == Transaction.GROCERY).
 sorted(comparing(Transaction::getValue).reversed()).
 map(Transaction::getId).
 collect(toList());

一、Stream 总览

1.什么是流

Stream 不是集合元素,它更像一个高级版本的 Iterator。用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。

而和迭代器又不同的是,Stream 可以并行化操作。使用并行模式时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。

Stream 的另外一大特点是,数据源本身可以是无限的。

2.流的构成

2.1三个基本步骤:

获取一个数据源(source)→ 数据转换→执行操作获取想要的结果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道,如下图所示。
图 1. 流管道 (Stream Pipeline) 的构成

2.2有多种方式生成 Stream Source:

从 Collection 和数组
Collection.stream()
Collection.parallelStream()
Arrays.stream(T array) or Stream.of()

从 BufferedReader

静态工厂

自己构建

其它
注:详见参考链接

2.3流的操作类型分为两种:

Intermediate:中间的 :一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。仅仅调用到这类方法,并没有真正开始流的遍历。

Terminal:终点站 :一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。

简单理解Intermediate和Termianl底层:Stream 里有个操作函数的集合,每次转换操作就是把转换函数放入这个集合中,在 Terminal 操作的时候循环 Stream 对应的集合,然后对每个元素执行所有的函数。

还有一种操作被称为 short-circuiting:短路
顾名思义,用以短路。用来保证:无限大的Stream,能进行有限的操作。

清单 3. 一个流操作的示例:

int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
 .mapToInt(w -> w.getWeight())
 .sum();

代码含义: stream() 获取当前小物件的 source,filter 和 mapToInt 为 intermediate 操作,进行数据筛选和转换,最后一个 sum() 为 terminal 操作,对符合条件的全部小物件作重量求和。


二、流的使用详解

简单说,对 Stream 的使用就是实现一个 filter-map-reduce 过程

1.流的构造与转换

清单 4. 构造流的几种常见方法

// 1. Individual values
Stream stream = Stream.of("a", "b", "c");
// 2. Arrays
String [] strArray = new String[] {
   "a", "b", "c"};
stream = Stream.of(strArray);
stream = Arrays.stream(strArray);
// 3. Collections
List<String> list = Arrays.asList(strArray);
stream = list.stream();

注:对于基本数值型,目前有三种对应的包装类型 Stream:

清单 5. 数值流的构造

IntStream.of(new int[]{
   1, 2, 3}).forEach(System.out::println);
IntStream.range(1, 3).forEach(System.out::
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值