规约操作
规约操作:通过某个连接动作将所有元素汇总成一个结果的过程。元素求和、求最大值或最小值、求出元素总个数、将所有元素转换成一个列表或集合,都属于规约操作。
Stream类库有两个通用的规约操作reduce()和collect()。还有专用规约操作: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:初始值;accumulator:收集规则(累加,长度等);combiner:并行执行时多个部分结果的合并方式。
reduce()常用的场景是从一堆值中生成一个值。
collect()
实例:
Stream<String> stream = Stream.of("","","");
List<String> list = stream.collect(Collectors.toList());
Set<String> set = stream.collect(Collectors.toSet());
Map<String, Integer> map = stream.collect(Collectors.toMap(Function.identity(), String::length));
将Stream转换成List,Set或是Map。
Function
@FunctionalInterfacepublic interface Function<T, R> { R apply(T t); default <V> Function<V, R> compose(Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } static <T> Function<T, T> identity() { return t -> t; }}
收集器(Collector)
收集器是为了Stream.collect()方法打造的工具接口。我们将Stream转换成集合或是Map,需要知道1,目标容器是什么?2,新元素如何添加到集合中?3,如果进行并行规约,多个部分结果如何合并成一个。
Stream.collect的方法定义:
<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
里面的三个参数分别对应上面的三个问号。这个方法可以收集任何形式你想要的信息,还有一个collect方法是对这三个参数的封装。
<R, A> R collect(Collector<? super T, A, R> collector);
Collectors类通过静态方法生成各种常用的收集器(Collector),Collectors.toList()返回生成List的收集器。Collectors.toMap()返回生成Map的收集器。
Collectors.toCollection(ArrayList::new)可以指定集合的具体类型
ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
现在重点说说生成map收集器
前面说Stream依赖数据源,数据源可以是数组,集合等。但是不会是map。但是我们可以从Stream生成Map。
1,Collectors.toMap():生成收集器,需要指定如何生成Map的key和value。
2,Collectors.partitioningBy():生成收集器,对元素进行二分区操作。依据某个条件分成两部分(满足条件和不满足条件)
3,Collectors.groupingBy():生成收集器,对元素做group操作。按照某个属性对元素进行分组,属性相同的元素被对应到map的同一个key上。groupingBy还运行对元素进行分组后再执行运算(求和,类型转换等操作)。先将元素分组的收集器叫做上游收集器,之后执行其他运算的收集器叫做下游收集器。
字符串拼接
字符串拼接时使用Collectors.joining()生成的收集器。
1,Stream.collect(Collectors.joining())。
2,Stream.collect(Collectors.joining(","))。// 按照逗号分隔符拼接字符串
3,Stream.collect(Collectors.joining(",","{","}"))。// 按照逗号分隔符拼接字符串,在最前端加“{”,在字符串末尾加“}”。
网友评论