Java 8 Stream API详解--转
原文地址:http://blog.csdn.net/chszs/article/details/47038607
Java 8 Stream API详解
一、Stream API介绍
Java8引入了全新的Stream API,此Stream与Java I/O包里的InputStream和OutputStream是完全不同的概念,它不同于StAX对XML解析的Stream,也不同于Amazon Kinesis对大数据实时处理的Stream。Stream API更像具有Iterable的集合类,但行为和集合类又有所不同,它是对集合对象功能的增强,专注于对集合对象进行各种非常便捷、高效的聚合操作或大批量数据操作。
Stream API引入的目的在于弥补Java函数式编程的缺陷。对于很多支持函数式编程的语言,map()、reduce()基本上都内置到语言的标准库中了,不过,Java 8的Stream API总体来讲仍然是非常完善和强大,足以用很少的代码完成许多复杂的功能。
Java 8的Stream API充分利用Lambda表达式的特性,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错,但使用Stream API无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。
在Stream API中,一个流基本上代表一个元素序列,Stream API提供了丰富的操作函数来计算这些元素。以前我们在开发业务应用时,通常很多操作的实现是这样做的:我们使用循环对集合做遍历,针对集合中的元素实现各种操作,定义各种变量来实现目的,这样我们就得到了一大堆丑陋的顺序代码。
如果我们使用Stream API做同样的事情,使用Lambda表达式和其它函数进行抽象,可以使得代码更易于理解、更为干净。有了这些抽象,还可以做一些优化,比如实现并行等。
二、Stream API实例
1. 使用IntStream移除常规的循环
比如在控制台输出0~9的例子:
注意需import java.util.stream.IntStream;
IntStream.range(0, 10).forEach(value -> System.out.println(value));
2. 计算列表中的元素数
注意需
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
List<Integer> list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
System.out.println(list.stream().count());
3. 计算列表中元素的平均数
Double avarage = list.stream().collect(Collectors.averagingInt(item -> item));
4. 对列表元素进行统计
List<Integer> list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
IntSummaryStatistics iss = list.stream().collect(Collectors.summarizingInt(value -> value));
System.out.println(iss);
输出结果:
IntSummaryStatistics{count=99, sum=4950, min=1, average=50.000000, max=99}
5. 根据List创建Map
List<Integer> list = IntStream.range(1, 100).boxed().collect(Collectors.toList());
Map<Integer, Integer> map = list.stream().collect(Collectors.toMap(p -> p, q->q*3));
System.out.println(map);
输出结果:
{1=3, 2=6, 3=9, 4=12, 5=15, 6=18, 7=21, 8=24, 9=27, 10=30, 11=33, 12=36, 13=39, 14=42, 15=45, 16=48, 17=51, 18=54, 19=57, 20=60, 21=63, 22=66, 23=69, 24=72, 25=75, 26=78, 27=81, 28=84, 29=87, 30=90, 31=93, 32=96, 33=99, 34=102, 35=105, 36=108, 37=111, 38=114, 39=117, 40=120, 41=123, 42=126, 43=129, 44=132, 45=135, 46=138, 47=141, 48=144, 49=147, 50=150, 51=153, 52=156, 53=159, 54=162, 55=165, 56=168, 57=171, 58=174, 59=177, 60=180, 61=183, 62=186, 63=189, 64=192, 65=195, 66=198, 67=201, 68=204, 69=207, 70=210, 71=213, 72=216, 73=219, 74=222, 75=225, 76=228, 77=231, 78=234, 79=237, 80=240, 81=243, 82=246, 83=249, 84=252, 85=255, 86=258, 87=261, 88=264, 89=267, 90=270, 91=273, 92=276, 93=279, 94=282, 95=285, 96=288, 97=291, 98=294, 99=297}
6. 求列表元素的最大数
List<Integer> list = new Random().ints(-100,100).limit(250).boxed().collect(Collectors.toList());
Optional<Integer> max = list.stream().reduce(Math::max);
max.ifPresent(value -> System.out.println(value));
7. 从一堆姓名列表中找出以字母“C”开头的姓名
String[] names = { "Fred Edwards", "Anna Cox", "Deborah Patterson", "Ruth Torres", "Shawn Powell",
"Rose Thompson", "Rachel Barnes", "Eugene Ramirez", "Earl Flores", "Janice Reed", "Sarah Miller",
"Patricia Kelly", "Carl Hall", "Craig Wright", "Martha Phillips", "Thomas Howard", "Steve Martinez",
"Diana Bailey", "Kathleen Hughes", "Russell Anderson", "Theresa Perry" };
List<String> ls = Arrays.asList(names).stream().filter(s -> s.startsWith("C")).collect(Collectors.toList());
System.out.println(ls.toString());
8. 把所有的姓名大写、排序,再输出
String[] names = { "Fred Edwards", "Anna Cox", "Deborah Patterson", "Ruth Torres", "Shawn Powell",
"Rose Thompson", "Rachel Barnes", "Eugene Ramirez", "Earl Flores", "Janice Reed", "Sarah Miller",
"Patricia Kelly", "Carl Hall", "Craig Wright", "Martha Phillips", "Thomas Howard", "Steve Martinez",
"Diana Bailey", "Kathleen Hughes", "Russell Anderson", "Theresa Perry" };
Arrays.asList(names)
.stream()
.map(String::toUpperCase)
.sorted().forEach(System.out::println);
三、更复杂的例子
1. 创建一个Person类
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return name;
}
}
2. 根据年龄对Person进行分组
Map<Integer, List<Person>> collect = persons.stream().collect(Collectors.groupingBy(Person::getAge));
3. 对所有Person求平均年龄
Double collect = persons.stream().collect(Collectors.averagingInt(Person::getAge));
Java 8 Stream API详解--转的更多相关文章
- Java 8 Stream API 详解
Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利.高效的聚合操作(aggregate operation),或者大批量数据操作 (b ...
- java 8 stream reduce详解和误区
目录 简介 reduce详解 总结 java 8 stream reduce详解和误区 简介 Stream API提供了一些预定义的reduce操作,比如count(), max(), min(), ...
- Java8学习笔记(五)--Stream API详解[转]
为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...
- Java 8 Streams API 详解
流式编程作为Java 8的亮点之一,是继Java 5之后对集合的再一次升级,可以说Java 8几大特性中,Streams API 是作为Java 函数式的主角来设计的,夸张的说,有了Streams A ...
- Java 8 Date-Time API 详解
从Java版本1.0开始就支持日期和时间,主要通过java.util.Date类. 但是,Date类设计不佳. 例如,Date中的月份从1开始,但从日期却从0开始.在JDK 1.1中使用它的许多方法已 ...
- Java中的java.lang.Class API 详解
且将新火试新茶,诗酒趁年华. 概述 Class是一个位于java.lang包下面的一个类,在Java中每个类实例都有对应的Class对象.类对象是由Java虚拟机(JVM)自动构造的. Class类的 ...
- Java8的Stream语法详解(转载)
1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...
- Java 8 Lambda 表达式详解
一.Java 8 Lambda 表达式了解 参考:Java 8 Lambda 表达式 | 菜鸟教程 1.1 介绍: Lambda 表达式,也可称为闭包,是推动 Java 8 发布的最重要新特性. La ...
- Java8初体验(二)Stream语法详解(转)
本文转自http://ifeve.com/stream/ Java8初体验(二)Stream语法详解 感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com上篇文章Java8初体验(一 ...
随机推荐
- Reading C type declarations(引用http://unixwiz.net/techtips/reading-cdecl.html)
Even relatively new C programmers have no trouble reading simple C declarations such as int foo[5]; ...
- Spark优化之三:Kryo序列化
Spark默认采用Java的序列化器,这里建议采用Kryo序列化提高性能.实测性能最高甚至提高一倍. Spark之所以不默认使用Kryo序列化,可能的原因是需要对类进行注册. Java程序中注册很简单 ...
- 【转】Android Studio-1.2版本设置教程
如果重新安装Android Studio的话要重新配置风格选项啥的,这篇是个很好的教程,原文链接:http://blog.csdn.net/skykingf/article/details/45485 ...
- CYQ.Data V4系列全面开源(2013-08-04)
致各位.NET开发者: 考虑到本人开源作品太多,个人维护力度有限,故自2013-08-04开始,开放原本需要授权使用的V4系列的最高版本V4.55的框架源码,同时也开放相对应的辅助工具源码,自此,V4 ...
- 又踩.NET Core的坑:在同步方法中调用异步方法Wait时发生死锁(deadlock)
之前在将 Memcached 客户端 EnyimMemcached 迁移 .NET Core 时被这个“坑”坑的刻骨铭心(详见以下链接),当时以为只是在构造函数中调用异步方法(注:这里的异步方法都是指 ...
- ABP理论学习之功能管理
返回总目录 本篇目录 介绍 功能类型 定义功能 检查功能 功能管理者 版本说明 介绍 大多数的Saas(多租户)应用都有不同 功能的 版本(包).因此,他们可以给租户(客户)提供不同的 价格和功能选项 ...
- .NET中使用APlayer组件自制播放器
目录 说明 APlayer介绍 APlayer具备功能 APlayer使用 自制播放器Demo 未完成工作 源码下载 说明 由于需求原因,需要在项目中(桌面程序)集成一个在线播放视频的功能.大概要具备 ...
- .NET平台下对C3D文件的读写
[题外话] 最近实验室要我修改C3D(The 3D Biomechanics Data Standard)文件,虽然从网上找到了一个叫c3d4sharp的类库,这个类库单纯读取C3D文件的话还可以,但 ...
- Mycat 全局系列号
标签:utf8 概述 本篇文章介绍mycat怎样在分库分表的情况下保证主键的全局唯一方法,接下来就来分析三种方法各自的优缺点. 配置 文件方式获取 1.修改server配置文件 vim server. ...
- 一个新人如何学习在大型系统中添加新功能和Debug
文章背景: 今年七月份正式入职,公司主营ERP软件,楼主所在的组主要负责二次开发,使用的语言是Java. 什么叫二次开发呢?ERP软件的客户都是企业.而这些企业之间的情况都有所不同,一套标准版本的企业 ...