JAVA8学习9-Collectors 类分析

9.2 Collectors 类分析

​ 对应 Collectors 静态工厂类来说,其实共分为两种情况:

  1. 通过 CollectorImpl 内部类来实现
  2. 通过 reducing 方法来实现,reducing 方法本身又是通过 CollectorImpl 来实现的

其实上面自定义的会了之外,看 Collectors 类的实现,都会感到很亲切的。这里不说了。介绍几个上面没用过的方法:

9.2.1 mapping 多级缩减映射

Collector<T, ?, R>mapping(Function<? super T, ? extends U> mapper, Collector<? super U, A, R> downstream) : mapping 收集器在多级缩减中最有用,例如 groupingBy或partitioningBy的下游。例如,给定Person的流,以累积每个城市中的名字集合:

Map<City,Set<String>>lastNamesByCity =
 people.stream().collect(groupingBy(Person::getLastName, 		mapping(Person::getLastName, toSet())));
9.2.2 collectingAndThen 结果集再映射

collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) 调整 Collector 以执行其他完成转换。例如,可以调整 toList()收集器以始终生成一个不可变列表:

 List<String> people = people.stream().collect(collectingAndThen(toList(), Collections::unmodifi
 ableList));
public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
                                                            Function<R,RR> finisher) {
   
    Set<Collector.Characteristics> characteristics = downstream.characteristics();
    if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) {
   // 这里移除了 IDENTITY_FINISH
        if (characteristics.size() == 1)
            characteristics = Collectors.CH_NOID;
        else {
   
            characteristics = EnumSet.copyOf(characteristics);
            characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
            characteristics = Collections.unmodifiableSet(characteristics);
        }
    }
    return new CollectorImpl<>(downstream.supplier(),
                               downstream.accumulator(),
                               downstream.combiner(),
                               downstream.finisher().andThen(finisher),//这里在finisher后再添加了一个 Function,downstream.finisher() 原来就是一个 Function
                               characteristics);
}

移除了 identity, 在 finisher 后 用了 andThen 方法。做到结果集转换为其他类型。

9.2.3 summingInt 求和

为什么要用数组,而最后返回数组的唯一一个元素?

public static <T> Collector<T, ?, Integer>
summingInt(ToIntFunction<? super T> mapper) {
   
    return new CollectorImpl<>(
            () -> new int[1],//为什么要用数组呢
            (a, t) -> {
    a[0] += mapper.applyAsInt(t); },
            (a, b) -> {
    a[0] += b[0]; return a; },
            a -> a[0], CH_NOID);
}

因为数组是个引用类型的,如果你弄的是数字,他就是固定值了,不能够传递。而且中间结果要求的是一个容器。

9.2.4 reducing 缩减数据源,对数据进行缩减操作,像求和、平均等都可以用该方法实现的,是一个收集器

reducing 实现:

使用identity初始值和op函数对输入的元素进行聚合操作

public static <T> Collector<T, ?, T>
reducing(T identity, BinaryOperator<T> op) {
   
    return new CollectorImpl<>(
            boxSupplier(identity),
            (a, t) -> {
    a[0] = op.apply(a[0], t); },
            (a, b) -> {
    a[0] = op.apply(a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值