栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java stream 之Collector

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java stream 之Collector

之前写过一篇嵌套的groupingBy,很简短。这次面试汇丰的时候遇到了一个Collectors.of()的使用方式直接抓瞎了。所以参考各位大佬的博客,阅读源码Collectors源码后决定留个笔记。有什么不对的麻烦指出,恳求指正。

先认识下它的五个重要参数

private final Supplier supplier;
private final BiConsumer accumulator;
private final BinaryOperator combiner;
private final Function finisher;
private final Set characteristics;

Supplier supplier是用来提供新的容器的。

BiConsumer accumulator 用于组装数据。把数据装到容器A。

BinaryOperator combiner;这个方法在collect方法的实现中完全没用到。在groupingby中会用到。

collect的实现

public final  R collect(Collector collector) {
    A container;
    if (isParallel()
            && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT))
            && (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) {
        container = collector.supplier().get();
        BiConsumer accumulator = collector.accumulator();
        forEach(u -> accumulator.accept(container, u));
    }
    else {
        container = evaluate(ReduceOps.makeRef(collector));
    }
    return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)
           ? (R) container
           : collector.finisher().apply(container);
}

groupingby的实现就要复杂很多。

public static >
Collector groupingBy(Function classifier,
                              Supplier mapFactory,
                              Collector downstream) {
    Supplier downstreamSupplier = downstream.supplier();
    BiConsumer downstreamAccumulator = downstream.accumulator();
    BiConsumer, T> accumulator = (m, t) -> {
        K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
        A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
        downstreamAccumulator.accept(container, t);
    };
    BinaryOperator> merger = Collectors.>mapMerger(downstream.combiner());
    @SuppressWarnings("unchecked")
    Supplier> mangledFactory = (Supplier>) mapFactory;

    if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
        return new CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
    }
    else {
        @SuppressWarnings("unchecked")
        Function downstreamFinisher = (Function) downstream.finisher();
        Function, M> finisher = intermediate -> {
            intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
            @SuppressWarnings("unchecked")
            M castResult = (M) intermediate;
            return castResult;
        };
        return new CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
    }
}

自定义Collector实现,combiner都没被使用。事实上只需要传递一个新的容器。然后实现往容器添加元素就好。

List list = new linkedList() {{
    add("aa");
    add("bb");
    add("ttt");
}};
HashMap map = list.stream().collect(Collector.of(HashMap::new, (r, t) -> {
    r.put(t, t.length());
}, (r1, r2) -> {
    //r1.putAll(r2);
    System.out.print("never used");
    return r1;
}));

后面补充下Collector接口和Collectors类的大致全貌。偷个懒下班先。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778162.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号