第6章 用流收集数据

第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))
  1. 把收集器的结果转换另一种类型 collectingAndThen
groupingBy(Dish::getType, 
    collectingAndThen(maxBy(comparingInt(Dish::getCalories)),
    Optional::get));
  1. 与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]

值得看看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值