首先看一个问题:在这个task集合中一共有多少个OPEN状态的?计算出它们的points属性和。在Java 8之前,要解决这个问题,则需要使用foreach循环遍历task集合;但是在Java 8中可以利用steams解决:包括一系列元素的列表,并且支持顺序和并行处理。

// Calculate total points of all active tasks using sum()
final long totalPointsOfOpenTasks = tasks
.stream()
.filter( task -> task.getStatus() == Status.OPEN )
.mapToInt( Task::getPoints )
.sum(); System.out.println( "Total points: " + totalPointsOfOpenTasks );

这里有很多知识点值得说。首先,tasks集合被转换成steam表示;其次,在steam上的filter操作会过滤掉所有CLOSEDtask;第三,mapToInt操作基于tasks集合中的每个task实例的Task::getPoints方法将task流转换成Integer集合;最后,通过sum方法计算总和,得出最后的结果。

在学习下一个例子之前,还需要记住一些steams(点此更多细节)的知识点。Steam之上的操作可分为中间操作和晚期操作。

中间操作会返回一个新的steam——执行一个中间操作(例如filter)并不会执行实际的过滤操作,而是创建一个新的steam,并将原steam中符合条件的元素放入新创建的steam。

晚期操作(例如forEach或者sum),会遍历steam并得出结果或者附带结果;在执行晚期操作之后,steam处理线已经处理完毕,就不能使用了。在几乎所有情况下,晚期操作都是立刻对steam进行遍历。

steam的另一个价值是创造性地支持并行处理(parallel processing)。对于上述的tasks集合,我们可以用下面的代码计算所有task的points之和:

// Calculate total points of all tasks
final double totalPoints = tasks
.stream()
.parallel()
.map( task -> task.getPoints() ) // or map( Task::getPoints )
.reduce( 0, Integer::sum ); System.out.println( "Total points (all tasks): " + totalPoints );

这里我们使用parallel方法并行处理所有的task,并使用reduce方法计算最终的结果。控制台输出如下:

对于一个集合,经常需要根据某些条件对其中的元素分组。利用steam提供的API可以很快完成这类任务,代码如下:

// Group tasks by their status
final Map< Status, List< Task > > map = tasks
.stream()
.collect( Collectors.groupingBy( Task::getStatus ) );
System.out.println( map );

控制台的输出如下:

{CLOSED=[[CLOSED, 8]], OPEN=[[OPEN, 5], [OPEN, 13]]}

最后一个关于tasks集合的例子问题是:如何计算集合中每个任务的点数在集合中所占的比重,具体处理的代码如下:

// Calculate the weight of each tasks (as percent of total points)
final Collection< String > result = tasks
.stream() // Stream< String >
.mapToInt( Task::getPoints ) // IntStream
.asLongStream() // LongStream
.mapToDouble( points -> points / totalPoints ) // DoubleStream
.boxed() // Stream< Double >
.mapToLong( weigth -> ( long )( weigth * 100 ) ) // LongStream
.mapToObj( percentage -> percentage + "%" ) // Stream< String>
.collect( Collectors.toList() ); // List< String > System.out.println( result );

控制台输出结果如下:

[19%, 50%, 30%]

最后,正如之前所说,Steam API不仅可以作用于Java集合,传统的IO操作(从文件或者网络一行一行得读取数据)可以受益于steam处理,这里有一个小例子:

final Path path = new File( filename ).toPath();
try( Stream< String > lines = Files.lines( path, StandardCharsets.UTF_8 ) ) {
lines.onClose( () -> System.out.println("Done!") ).forEach( System.out::println );
}

Stream的方法onClose() 返回一个等价的有额外句柄的Stream,当Stream的close()方法被调用的时候这个句柄会被执行。Stream API、Lambda表达式还有接口默认方法和静态方法支持的方法引用,是Java 8对软件开发的现代范式的响应。

java8的Streams的更多相关文章

  1. Java8高中并发

    Java8中学并发 本文翻译自:http://jaxenter.com/lean-concurrency-in-java-8-49924.html 转载请注明出处:http://blog.csdn.n ...

  2. Java8之Stream/Map

    本篇用代码示例结合JDk源码讲了Java8引入的工具接口Stream以及新Map接口提供的常用默认方法.    参考:http://winterbe.com/posts/2014/03/16/java ...

  3. Java笔记——Java8特性之Lambda、方法引用和Streams

    Java8已经推出了好一段时间了,而掌握Java8的新特性也是必要的,如果要进行Spring开发,那么可以发现Spring的官网已经全部使用Java8来编写示例代码了,所以,不学就看不懂. 这里涉及三 ...

  4. Java8中 Parallel Streams 的陷阱 [译]

    译注:文本有所精简和意译 原文链接 : Java Parallel Streams Are Bad for Your Health!原作者:OLEG SHELAJEV 翻译:Hason 转载请保留相关 ...

  5. Java8特性之Lambda、方法引用和Streams

    这里涉及三个重要特性: Lambda 方法引用 Streams ① Lambda 最早了解Lambda是在C#中,而从Java8开始,Lambda也成为了新的特性,而这个新的特性的目的,就是为了消除单 ...

  6. Java8 新特性 Streams map() 示例

    在Java 8中stream().map(),您可以将对象转换为其他对象.查看以下示例: 1.大写字符串列表 1.1简单的Java示例将Strings列表转换为大写. TestJava8.java p ...

  7. Java8 Streams 让集合操作飞起来

    前言 接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Stream 重点说明 ,并做了点补充. 基本说明 Stream 是基于 java8 的 lam ...

  8. Java8的新特性以及与C#的比较

    函数式接口 VS 委托 在C中,可以使用函数指针来存储函数的入口,从而使得函数可以像变量一样赋值.传递和存储,使得函数的调用变得十分灵活,是实现函数回调的基础.然而函数指针不存在函数的签名信息,甚至可 ...

  9. Java8初体验(二)Stream语法详解

    感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 上篇文章Java8初体验(一)lambda表达式语法比 较详细的介绍了lambda表达式的方方面面,细心的读者会发现那篇文章的例 ...

随机推荐

  1. PHUML 生成UML类图操作流程

    项目基础阶段: 安装svn,因为托管在svn平台上: 项目下载到本地,并切换到对应目录(如:F:\wwwroot\phuml.git\trunk\src\app): svn checkout http ...

  2. 搭建Google镜像网站

    很多人FQ或者买VPN账号仅仅只是为了使用Google搜索.相对于搭建VPN服务器来说,下面的方法搭建Google镜像网站将更加便捷. 条件:最好有自己的域名(可选),有可以正常访问Google的服务 ...

  3. CRT and exlucas

    CRT 解同余方程,形如\(x \equiv c_i \ mod \ m_i\),我们对每个方程构造一个解满足: 对于第\(i\)个方程:\(x \equiv 1 \ mod \ m_i\),\(x ...

  4. Android GPS定位测试(附效果图)

    今天因为工作需要,把以前编写的一个GPS测试程序拿出来重新修改了一下.这个程序说起来有些历史了,是我11年编写的,那时候学了Android开发没多久,算是一个实验性的作品.现在工作需要,重新拿出来修整 ...

  5. [ZJOI2016]大森林(LCT)

    题目描述 小Y家里有一个大森林,里面有n棵树,编号从1到n.一开始这些树都只是树苗,只有一个节点,标号为1.这些树都有一个特殊的节点,我们称之为生长节点,这些节点有生长出子节点的能力. 小Y掌握了一种 ...

  6. 汽车控制器LIMPHOME电路设计

    摘要:本文介绍汽车控制器上常用的3种LIMPHOME电路设计方法,用于在单片机复位重启期间仍能保证外部输出正确性,确保行车安全.    在电子电气领域,单片机使用非常广泛,单片机的复位重启是设计时必须 ...

  7. RHEL7下用本地光盘或镜像iso文件做yum源

    应用场境:Redhat 系统想要直接在线通过yum的条件时需要注册,一般用户都是非注册的,这个时候如果要想通过yum安装新软件,我们可以通过将安装盘或者镜像iso文件设置为yum源的方式来进行. 测试 ...

  8. js 刷新

    方法一: location.reload 重新加载 location.reload(); 如果该方法没有规定参数,或者参数是 false,它就会用 HTTP 头 If-Modified-Since 来 ...

  9. Python使用import导入相对路径的其他py文件

    假如有如下的目录结构 . ├── setup.py ├── main.py ├── mod/ │   └── mod.py └── sub/ └── sub.py 情况1:setup.py导入main ...

  10. 洛谷P3168 任务查询系统

    题意:有n个任务,第i个的存在时间是li~ri,有个权值.求t时刻第k大的权值. 这毒瘤...本来是前缀和 -> 主席树,我是树套树...然后光荣TLE. 其实很裸.一开始我写的是每个位置维护一 ...