前言:

JDK 12中添加了一个新的流API收集器:Teeing()。

Collectors#teeing

简单地说,它允许使用两个独立的收集器收集流,然后使用提供的双功能合并结果。

例如,通过使用它可以计算所有流值的预期值:


// import static java.util.stream.Collectors.*;
Double ev = Stream.of(1, 2, 3, 4, 5, 6) // dice roll.collect(teeing(summingDouble(i -> i),counting(),(sum, n) -> sum / n));
System.out.println(ev); // 3.5

或者可以派生一个新的收集器,它也可以这样做:

private static Collector<Integer, ?, Double> derivingExpectedValue() {return teeing(summingDouble(i -> i),counting(),(sum, n) -> sum / n);
}
Double ev = Stream.of(1, 2, 3, 4, 5, 6).collect(derivingExpectedValue());

Teeing() 同 Collectors#groupingBy. 的使用: https://4comprehension.com/the-ultimate-guide-to-the-java-stream-api-groupingby-collector/

 JDK12之前

Integer[] stream = Stream.of(1, 2, 3, 4, 5, 6).toArray(Integer[]::new);
Double ev = IntStream.range(0, stream.length).boxed().reduce(0d, (acc, i) -> acc + (((double) stream[i]) / stream.length), (acc1, acc2) -> cc1 + acc2);

或者


Integer[] stream = Stream.of(1, 2, 3, 4, 5, 6).toArray(Integer[]::new);
double ev = 0d;
for (Integer integer : stream) {ev = ev + (((double) integer) / stream.length);
}

实现机制:

public static <T, R1, R2, R> Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,Collector<? super T, ?, R2> downstream2,BiFunction<? super R1, ? super R2, R> merger) {return teeing0(downstream1, downstream2, merger);
}
private static <T, A1, A2, R1, R2, R> Collector<T, ?, R> teeing0(Collector<? super T, A1, R1> downstream1,Collector<? super T, A2, R2> downstream2,BiFunction<? super R1, ? super R2, R> merger) {Objects.requireNonNull(downstream1, "downstream1");Objects.requireNonNull(downstream2, "downstream2");Objects.requireNonNull(merger, "merger");Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");BiConsumer<A1, ? super T> c1Accumulator = Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");BiConsumer<A2, ? super T> c2Accumulator = Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");BinaryOperator<A2> c2Combiner = Objects.requireNonNull(downstream2.combiner(), "downstream2 combiner");Function<A1, R1> c1Finisher = Objects.requireNonNull(downstream1.finisher(), "downstream1 finisher");Function<A2, R2> c2Finisher = Objects.requireNonNull(downstream2.finisher(), "downstream2 finisher");Set<Collector.Characteristics> characteristics;Set<Collector.Characteristics> c1Characteristics = downstream1.characteristics();Set<Collector.Characteristics> c2Characteristics = downstream2.characteristics();if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {characteristics = CH_NOID;} else {EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);c.addAll(c1Characteristics);c.retainAll(c2Characteristics);c.remove(Collector.Characteristics.IDENTITY_FINISH);characteristics = Collections.unmodifiableSet(c);}class PairBox {A1 left = c1Supplier.get();A2 right = c2Supplier.get();void add(T t) {c1Accumulator.accept(left, t);c2Accumulator.accept(right, t);}PairBox combine(PairBox other) {left = c1Combiner.apply(left, other.left);right = c2Combiner.apply(right, other.right);return this;}R get() {R1 r1 = c1Finisher.apply(left);R2 r2 = c2Finisher.apply(right);return merger.apply(r1, r2);}}return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get, characteristics);
}

详情参考: https://bugs.openjdk.java.net/browse/JDK-8209685


JDK12 Stream Api : teeing()相关推荐

  1. 【Java8新特性】关于Java8的Stream API,看这一篇就够了!!

    写在前面 Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*)  ,那什么是Stream API呢?Java8中 ...

  2. Java 8中Stream API的这些奇技淫巧!你都Get到了吗?

    作者:我是你的小眼睛儿 https://www.jianshu.com/p/9fe8632d0bc2 Stream简介 1.Java 8引入了全新的Stream API.这里的Stream和I/O流不 ...

  3. 使用 Stream API 高逼格 优化 Java 代码!

    作者 | 何甜甜在吗 来源 | https://juejin.cn/post/6844903945005957127 使用Stream API优化代码 Java8的新特性主要是Lambda表达式和流, ...

  4. Java 8 中 Stream API 的奇技淫巧

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 我是你的小眼睛儿 来源 | jianshu.c ...

  5. Java 8 Stream Api 中的 map和 flatMap 操作

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「码农小胖哥」 1.前言 Java 8  ...

  6. Java 8 Stream Api 中的 skip 和 limit 操作

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 Java 8 Stream API 中的sk ...

  7. java遍历栈_Java中使用StackWalker和Stream API进行堆栈遍历

    1.Java 9以前堆栈遍历到目前为止,官方解决方案是获取当前线程并调用其getStackTrace()方法: StackTraceElement[] stackTraceElements = Thr ...

  8. Atitit 实现java的linq 以及与stream api的比较

    Atitit 实现java的linq 以及与stream api的比较 1.1. Linq 和stream api的关系,以及主要优缺点1 1.2. Linq 与stream api的适用场景1 1. ...

  9. java8新特性-lambda表达式和stream API的简单使用

    一.为什么使用lambda Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风 ...

最新文章

  1. 老板要我开发一个简单的工作流引擎
  2. Python 操作数据库(1)
  3. C++ 常见bug记录(持续记录中)
  4. 解决ios10以上H5页面手势、双击缩放问题
  5. Cron表达式【一】
  6. linux中group命令详解,linux groupmod命令参数及用法详解
  7. wifi不断重连报错:eSIR_MAC_CLASS3_FRAME_FROM_NON_ASSOC_STA_REASON解决
  8. Mac下Eclipse内置Tomcat端口被占用问题的解决办法
  9. marlab中主成分得分怎么求_PCA(主成分分析) 和 SVD (奇异值分解)
  10. 阿里AndFix与sophix热修复原理解析
  11. python 读取pdf图片_三种方法,Python轻松提取PDF中全部图片
  12. c语言怎么移位,C语言中的移位操作
  13. mysql master sevler_零零星星
  14. 爬虫模拟用户增加阅读量
  15. C# 传递数组参数_一维数组_二维数组
  16. 大规模时间序列数据自动异常检测架构
  17. 猫眼电影爬取(woff 字体文件解析)
  18. win7重装的坑:启动分区不存在 使用分区工具修正
  19. C# 正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。
  20. 19级算法训练赛第七场

热门文章

  1. Unity悬浮球自动吸附靠边
  2. 如何使用手刹解密和翻录DVD
  3. GBase 8s 备份介绍
  4. 《在线草图理解技术研究》博士论文复现
  5. html5中footer元素的作用,html5 footer标签怎么用?footer标签的用法实例
  6. 智能门锁的常识点及独一无二的体验
  7. 编程语言的发展趋势:从没有分号,到DSL
  8. C语言中的几种排序算法
  9. 20天等待,申请终于通过,安装和体验IntelliJ IDEA新UI预览版
  10. 交换友情链接看什么?