第6章 用流收集数据
6.1 收集器简介
你只需指出希望的结果 —— “做什么”,而不用操心执行的步骤 —— “如何做”
6.1.1 收集器用做高级规约
对流调用collect方法将对流中的元素触发一个规约操作。
6.1.2 预定义收集器
注意:Colletors实用类
- 将流元素规约和汇总为一个值。
- 元素分组
- 元素分区
6.2 规约和汇总
import static java.util.stream.Collectors.*;
- Collectors.counting
- stream().count
6.2.1 查找流中的最大值和最小值
- Collectors.maxBy
- Collectors.minBy
6.2.2 汇总
- Collectors.summingInt
- Collectors.summingLong
- Collectors.summingDouble
- Collectors.averagingInt
- Collectors.averagingLong
- Collectors.averagingDouble
- Collectors.summarizingInt
- Collectors.summarizingLong
- Collectors.summarizingDouble
6.2.3 连接字符串
- Collectors.joining
6.2.4 广义的归约汇总
- 对比:收集和归约的不同
- 收集器,都是一个可以用reducing工厂方法定义的归约过程的特殊情况。
- Collectors.reducing工厂方法是所有这些特殊情况的一般化。
Stream().reduce与Collectors.reduce不同的参数对比
Stream().reduce
* @param identity the identity value for the combiner function
* @param accumulator an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function for incorporating an additional element into a result
* @param combiner an <a href="package-summary.html#Associativity">associative</a>,
* <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* function for combining two values, which must be
* compatible with the accumulator function
* @return the result of the reduction
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
Collectors.reduce
* @param identity the identity value for the reduction (also, the value
* that is returned when there are no input elements)
* @param mapper a mapping function to apply to each input value
* @param op a {@code BinaryOperator<U>} used to reduce the mapped values
* @return a {@code Collector} implementing the map-reduce operation
public static <T, U>
Collector<T, ?, U> reducing(U identity,
Function<? super T, ? extends U> mapper,
BinaryOperator<U> op) {
return new CollectorImpl<>(
boxSupplier(identity),
(a, t) -> { a[0] = op.apply(a[0], mapper.apply(t)); },
(a, b) -> { a[0] = op.apply(a[0], b[0]); return a; },
a -> a[0], CH_NOID);
}
sum的4中方案对比
stream.collect(Collectors.reducing(0, n -> 1, Integer::sum));
stream.collect(Collectors.counting);
stream.reduce(Integer::sum);
stream.mapToInt(n -> n).sum();
根据情况选择最佳解决方案,上面最优方案可能是第4个,IntStream.sum()
6.3 分组 groupingBy
6.3.1 多级分组
嵌套groupingBy
6.3.2 按子组收集数据
groupingBy(Dish::getType, counting())
groupingBy(Dish::getType, toList())
groupingBy(Dish::getType, maxBy(comparingInt(Dish::getCalories))
- 把收集器的结果转换另一种类型 collectingAndThen
groupingBy(Dish::getType,
collectingAndThen(maxBy(comparingInt(Dish::getCalories)),
Optional::get));
- 与groupingBy联合使用的其他收集器的例子
- summingInt
groupingBy(Dish::getType, summingInt(Dish::getCalories))
- mapping
groupingBy(Dish::getType,
mapping(Dish::getCaloryType, toSet())
)
groupingBy(Dish::getType,
mapping(Dish::getCaloryType, toCollection(HashSet::new))
)
6.4 分区 partitioningBy
partitioningBy(Dish::isVegetarian, groupingBy(Dish::getType))
partitioningBy(Dish::isVegetarian,
collectionAndThen(
maxBy(comparingInt(Dish::getCalories)), Optional::get)
))
6.4.2 将数字按质数和非质数分区[P128]
partitioningBy
Collectors类的静态工厂方法
- collect(toList())
- collect(toSet())
- collect(toCollection(), ArrayList::new)
- collect(counting())
- collect(summingInt(Dish::getCalories))
- collect(averagingInt(Dish::getCalories))
- collect(summarizingInt(Dish::getCalories))
- collect(joining(", "))
- collect(maxBy(comparingInt(Dish::getCalories)))
- collect(minBy(comparingInt(Dish::getCalories)))
- collect(reducing(0, Dish::getCalories, Integer::sum))
- collect(collectingAndThen(toList(), List::size))
- collect(groupingBy(Dish::getType))
- collect(partitioningBy(Dish::isVegetarian))
6.5 收集器接口[*]
public interface Collector<T, A, R> {
// 建立新的结果容器
Supplier<A> supplier();
// 将元素添加到结果容器
BiConsumer<A, T> accumulator();
// 合并两个结果容器(并行归约)
BinaryOperator<A> combiner();
// 将结果容器应用最终转换
Function<A, R> finisher();
// 返回不可变的收集器行为枚举
Set<Characteristics> characteristics();
enum Characteristics {
CONCURRENT,
UNORDERED,
IDENTITY_FINISH
}
}
6.5.2 全部融合到一起[P134]
可以看看
6.6 开发你自己的收集器以获得更好的性能[P135]
值得看看