上一节先容了部门Stream常见接口要领,领略起来并不坚苦,但Stream的用法不止于此,本节我们将仍然以Stream为例,先容流的规约操纵。
规约操纵(reduction operation)又被称作折叠操纵(fold),是通过某个毗连行动将所有元素汇总成一个汇总功效的进程。元素求和、求最大值或最小值、求出元素总个数、将所有元素转换成一个列表或荟萃,都属于规约操纵。Stream类库有两个通用的规约操纵reduce()
和collect()
,也有一些为简化书写而设计的专用规约操纵,软件开发,好比sum()
、max()
、min()
、count()
等。
最大或最小值这类规约操纵很好领略(至少要领语义上是这样),我们着重先容reduce()
和collect()
,这是较量有邪术的处所。
多面手reduce()
reduce操纵可以实现从一组元素中生成一个值,sum()
、max()
、min()
、count()
等都是reduce操纵,将他们单独设为函数只是因为常用。reduce()
的要领界说有三种重写形式:
Optional<T> reduce(BinaryOperator<T> accumulator)
T reduce(T identity, BinaryOperator<T> accumulator)
<U> U reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)
固然函数界说越来越长,劳务派遣管理系统,但语义未曾改变,多的参数只是为了指明初始值(参数identity),可能是指定并行执行时多个部门功效的归并方法(参数combiner)。reduce()
最常用的场景就是从一堆值中生成一个值。用这么巨大的函数去求一个最大或最小值,你是不是以为设计者有病。其实否则,因为“大”和“小”可能“求和”有时会有差异的语义。
需求:从一组单词中找出最长的单词。这里“大”的寄义就是“长”。
// 找出最长的单词![](http://images2015.cnblogs.com/blog/939998/201703/939998-20170314192638495-351834305.png) Stream<String> stream = Stream.of("I", "love", "you", "too"); Optional<String> longest = stream.reduce((s1, s2) -> s1.length()>=s2.length() ? s1 : s2); //Optional<String> longest = stream.max((s1, s2) -> s1.length()-s2.length()); System.out.println(longest.get());
上述代码会选出最长的单词love,个中Optional是(一个)值的容器,利用它可以制止null值的贫苦。虽然可以利用Stream.max(Comparator<? super T> comparator)
要领来到达同等结果,但reduce()
自有其存在的来由。
需求:求出一组单词的长度之和。这是个“求和”操纵,操纵工具输入范例是String,而功效范例是Integer。
// 求单词长度之和 Stream<String> stream = Stream.of("I", "love", "you", "too"); Integer lengthSum = stream.reduce(0, // 初始值 // (1) (sum, str) -> sum+str.length(), // 累加器 // (2) (a, b) -> a+b); // 部门和拼接器,并行执行时才会用到 // (3) // int lengthSum = stream.mapToInt(str -> str.length()).sum(); System.out.println(lengthSum);
上述代码标号(2)处将i. 字符串映射生长度,ii. 并和当前累加和相加。这显然是两步操纵,利用reduce()
函数将这两步合二为一,更有助于晋升机能。假如想要利用map()
和sum()
组合来到达上述目标,也是可以的。
reduce()
擅长的是生成一个值,假如想要从Stream生成一个荟萃可能Map等巨大的工具该怎么办呢?终极兵器collect()
横空出世!
>>> 终极兵器collect() <<<
不浮夸的讲,假如你发明某个成果在Stream接口中没找到,十有八九可以通过collect()
要领实现。collect()
是Stream接口要领中最机动的一个,学会它才算真正入门Java函数式编程。先看几个热身的小例子:
// 将Stream转换成容器或Map Stream<String> stream = Stream.of("I", "love", "you", "too"); List<String> list = stream.collect(Collectors.toList()); // (1) // Set<String> set = stream.collect(Collectors.toSet()); // (2) // Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length)); // (3)