Java 8 新特性-菜鸟教程 (5) -Java 8 Stream
Java 8 Stream
Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
+--------------------+ +------+ +------+ +---+ +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+ +------+ +------+ +---+ +-------+
以上的流程转换为 Java 代码为:
List<Integer> transactionsIds =
widgets.stream()
.filter(b -> b.getColor() == RED)
.sorted((x,y) -> x.getWeight() - y.getWeight())
.mapToInt(Widget::getWeight)
.sum();
什么是 Stream?
Stream(流)是一个来自数据源的元素队列并支持聚合操作
元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
- 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。
和以前的Collection操作不同, Stream操作还有两个基础的特征:
- Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
- 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。
生成流
在 Java 8 中, 集合接口有两个方法来生成流:
stream() − 为集合创建串行流。
parallelStream() − 为集合创建并行流。
package java8.cainiao; import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors; import org.junit.Test; public class Java8Tester5 { /**
* Stream 提供了新的方法 'forEach' 来迭代流中的每个数据。以下代码片段使用 forEach 输出了10个随机数:
*/
@Test
public void test1(){
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
} /**
* map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:
*/
@Test
public void test2(){
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
squaresList.forEach(f -> System.out.println(f));
} /**
* filter 方法用于通过设置的条件过滤出元素。以下代码片段使用 filter 方法过滤出空字符串:
*/
@Test
public void test3(){
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.stream().filter(string -> string.isEmpty()).count();
System.out.println(count);
} /**
* limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:
*/
@Test
public void test4(){
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
} /**
* sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:
*/
@Test
public void test5(){
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
} /**
* 并行(parallel)程序
* parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:
*/
@Test
public void test6(){
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 获取空字符串的数量
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
System.out.println(count);
} /**
* Collectors
* Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串
*/
@Test
public void test7(){
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList()); System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);
} /**
* 统计
* 另外,一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上,它们可以用来产生类似如下的统计结果。
*/
@Test
public void test8(){
List<Integer> integers = Arrays.asList(3, 2, 2, 3, 7, 3, 5); IntSummaryStatistics stats = integers.stream().mapToInt((x) -> x).summaryStatistics(); System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
} }
Java 8 新特性-菜鸟教程 (5) -Java 8 Stream的更多相关文章
- Java 8 新特性-菜鸟教程 (0) -Java 8 新特性
Java 8 新特性 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本. Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 ...
- Java 8 新特性-菜鸟教程 (7) -Java 8 Nashorn JavaScript
Java 8 Nashorn JavaScript Nashorn 一个 javascript 引擎. 从JDK 1.8开始,Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java ...
- Java 8 新特性-菜鸟教程 (1) -Java 8 Lambda 表达式
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). 使用 Lambda 表达式可以使代码变的更加 ...
- Java 8 新特性-菜鸟教程 (4) -Java 8 默认方法
Java 8 默认方法 Java 8 新增了接口的默认方法. 简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法. 我们只需在方法名前面加个default关键字即可实现默认方法. 为 ...
- Java 8 新特性-菜鸟教程 (8) -Java 8 日期时间 API
Java 8 日期时间 API Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理. 在旧版的 Java 中,日期时间 API 存在诸多问题,其中有: ...
- Java 8 新特性-菜鸟教程 (3) -Java 8 函数式接口
Java 8 函数式接口 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为lambda表达式. 函数式接 ...
- Java 8 新特性-菜鸟教程 (6) -Java 8 Optional 类
Java 8 Optional 类 Optional 类是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. Optional 是个容 ...
- Java 8 新特性-菜鸟教程 (2) -Java 8 方法引用
Java 8 方法引用 方法引用通过方法的名字来指向一个方法. 方法引用可以使语言的构造更紧凑简洁,减少冗余代码. 方法引用使用一对冒号 :: . 下面,我们在 Car 类中定义了 4 个方法作为例子 ...
- Java 8 新特性-菜鸟教程 (9) -Java8 Base64
Java8 Base64 在Java 8中,Base64编码已经成为Java类库的标准. Java 8 内置了 Base64 编码的编码器和解码器. Base64工具类提供了一套静态方法获取下面三种B ...
随机推荐
- how to adjust PKG_CONFIG_PATH environment-variable
PKG_CONFIG_PATH is a environment variable that specifies additional paths in which pkg-config will s ...
- 如何通过RNA-Seq了解转录本的结构
[转载]如何通过RNA-Seq了解转录本的结构 已有 1942 次阅读 2014-12-26 15:22 |个人分类:转录组测序|系统分类:科研笔记|关键词:RNA-Seq,转录组测序,转录本结构| ...
- BZOJ1026或洛谷2657 [SCOI2009]windy数
BZOJ原题链接 洛谷原题链接 简单的数位\(DP\),套模板就好. #include<cstdio> #include<cstring> using namespace st ...
- 设计模式学习心得<建造者 Builder>
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 一个 Builder 类会一步一步构造最 ...
- 【APP测试(Android)】--功能
- AX_NumberSeq
NumberSeq::newGetNum(NumberSeqReference::findReference(typeId2ExtendedTypeId(typeid(InventTransId))) ...
- You are using pip version 9.0.1, however version 9.0.3 is available.
1,pip不能用了,提示:You are using pip version 8.1.1, however version 9.0.1 is available.网上搜索了一箩筐的安装程序,各种安装, ...
- To me
1.流泪的时候不做任何决定: 2.不反复思考同一个问题: 3.不害怕做错什么: 4.有负面情绪是正常的: 5.一切的烦恼都是自找的: 6.说过的话一定要做到: 7.不要去害怕做一件事: 8.无论是对是 ...
- .gitignore无效解决方案以及git rm和rm的区别
一. gitignore 先来了解一下gitignore的常用语法 斜杠“/”表示目录, 是否已斜杠开头有很大区别,如 /build 与 build/ 的区别:其中 build/ 表示不管在哪个位置的 ...
- springmvc接收数组方式总结
1.接受正常的数组 如param1=aaa¶m1=bbb¶m1=3 对于这种,在实体参数中,使用String param1[] 这种参数既可以获取数组的值 2.接受数组 ...