JDK12 Stream Api : teeing()


前言:

    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 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  Collector teeing(
  Collector downstream1,
  Collector downstream2,
  BiFunction merger) {
    return teeing0(downstream1, downstream2, merger);
}
private static  Collector teeing0(
  Collector downstream1,
  Collector downstream2,
  BiFunction merger) {
    Objects.requireNonNull(downstream1, "downstream1");
    Objects.requireNonNull(downstream2, "downstream2");
    Objects.requireNonNull(merger, "merger");
    Supplier c1Supplier = Objects.requireNonNull(
      downstream1.supplier(), "downstream1 supplier");
    Supplier c2Supplier = Objects.requireNonNull(
      downstream2.supplier(), "downstream2 supplier");
    BiConsumer c1Accumulator = Objects.requireNonNull(
      downstream1.accumulator(), "downstream1 accumulator");
    BiConsumer c2Accumulator = Objects.requireNonNull(
      downstream2.accumulator(), "downstream2 accumulator");
    BinaryOperator c1Combiner = Objects.requireNonNull(
      downstream1.combiner(), "downstream1 combiner");
    BinaryOperator c2Combiner = Objects.requireNonNull(
      downstream2.combiner(), "downstream2 combiner");
    Function c1Finisher = Objects.requireNonNull(
      downstream1.finisher(), "downstream1 finisher");
    Function c2Finisher = Objects.requireNonNull(
      downstream2.finisher(), "downstream2 finisher");
    Set characteristics;
    Set c1Characteristics = downstream1
      .characteristics();
    Set c2Characteristics = downstream2
      .characteristics();
    if (CH_ID.containsAll(c1Characteristics) 
      || CH_ID.containsAll(c2Characteristics)) {
        characteristics = CH_NOID;
    } else {
        EnumSet 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


 

你可能感兴趣的:(java,stream,Java)