参考并建议阅读《Java8函数式编程》
/《java 8 实战》
----------------------------------------------------------------------------------------------------------------------------------
什么是流?
流是Java API的新成员,它允许你以声明性的方式处理数据集合。它使得程序员得以站在更高的抽象层次上对集合进行操作。
- 声明性-----更简洁,更易读
- 可复合-----更灵活
- 可并行-----性能更好
流到底是什么?java8实战中说到”从支持数据处理操作的源生成的元素序列“。
- 元素序列-----就像集合一样,流也提供了一个接口,可以访问特定元素类型的一组有序值。
- 源-----流会使用一个提供数据的源,如集合,数组或输入/输出资源。
- 数据处理操作-----流的数据处理功能支持类似于数据库的操作,以及函数式编程语言中的常用操作,可以是顺序执行也可以是并行执行。
- 流水线----很多流操作本身会返回一个流,这样多个操作就可以链接起来,形成一个大的流水线。提供了一些优化成为可能,如延迟和短路。流水线的操作可以看作对数据源进行数据库式查询。
- 内部迭代----与使用迭代器显式迭代的集合不同,流的迭代操作是在背后进行的。
从外部迭代到内部迭代
一般在使用结合类时,一个通用的模式时在集合上进行迭代,然后处理返回的每一个元素,需要用户去做迭代(比如for-each),这称为外部迭代。相反,Stream库使用内部迭代----它帮你把迭代做了,还把值存在了某个地方,只要给出一个函数说要做什么就可以了。
外部迭代如图:
内部迭代如图:
外部迭代和内部迭代的主要差别,外部迭代你需要关心每一步,自己要管理所有的并行问题,内部迭代可以更清晰的表达你想要做什么,而怎么迭代你并不关心,Stream可以自动选择一种适合你硬件的数据表示和并行实现。
流的操作
流的使用一般包括三件事:
- 一个数据源来执行一个查询;
- 一个中间操作链,形成一个条流的流水线;
- 一个终端操作,执行流水线,并能生成结果。
中间操作:会返回一个流,这让多个操作可以连接起来形成要给查询,除非流水线上触发了一个终端操作,否则中间操作不会执行任何处理。
终端操作:会从流的流水线生成结果,其结果时任何不是流的值。
中间操作
终端操作
常用的流操作
collect(toList())
此方法有Steam里的值生成一个列表,是一个及早求值的操作。
List<String> collected = Stream.of("a", "b", "c") .collect(Collectors.toList());
assertEquals(Arrays.asList("a", "b", "c"), collected);
map
如果有一个函数可以将一种类型的值转换成另外一种类型,map操作就可以使用该函数,将一个流中的值转换成一个新的流 。
List<String> collected = Stream.of("a", "b", "hello").map(string -> string.toUpperCase()).collect(toList());
assertEquals(asList("A", "B", "HELLO"),collected);
map操作示意图
filter
遍历数据并检查其中的元素时,可尝试使用 Stream 中提供的新方法 filter 。其核心思想时保留Stream中的一些元素,而过滤掉其他的。
List<String> beginningWithNumbers= Stream.of("a", "1abc", "abc1").filter(value -> isDigit(value.charAt(0))).collect(toList());
assertEquals(asList("1abc"), beginningWithNumbers);
filter示意图
flatMap
将多个列表扁平化成一个列表。
List<Integer> together = Stream.of(asList(1, 2), asList(3, 4)).flatMap(numbers ->numbers.stream()).collect(toList());
assertEquals(asList(1, 2, 3, 4),together);
flatMap示意图
reduce
操作可以实现从一组值中生成一个值 ,如下面都求和操作。
int count = Stream.of(1, 2, 3).reduce(0, (acc, element) -> acc + element);
assertEquals(6, count);
reduce求和示意图