| /* |
| * Copyright 2016 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package java.util.stream; |
| |
| import static javaemul.internal.InternalPreconditions.checkState; |
| |
| import java.util.Arrays; |
| import java.util.DoubleSummaryStatistics; |
| import java.util.OptionalDouble; |
| import java.util.PrimitiveIterator; |
| import java.util.Spliterator; |
| import java.util.Spliterators; |
| import java.util.function.BiConsumer; |
| import java.util.function.DoubleBinaryOperator; |
| import java.util.function.DoubleConsumer; |
| import java.util.function.DoubleFunction; |
| import java.util.function.DoublePredicate; |
| import java.util.function.DoubleSupplier; |
| import java.util.function.DoubleToIntFunction; |
| import java.util.function.DoubleToLongFunction; |
| import java.util.function.DoubleUnaryOperator; |
| import java.util.function.ObjDoubleConsumer; |
| import java.util.function.Supplier; |
| |
| /** |
| * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/DoubleStream.html"> |
| * the official Java API doc</a> for details. |
| */ |
| public interface DoubleStream extends BaseStream<Double, DoubleStream> { |
| |
| /** |
| * See <a |
| * href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/DoubleStream.Builder.html">the |
| * official Java API doc</a> for details. |
| */ |
| interface Builder extends DoubleConsumer { |
| @Override |
| void accept(double t); |
| |
| default DoubleStream.Builder add(double t) { |
| accept(t); |
| return this; |
| } |
| |
| DoubleStream build(); |
| } |
| |
| static Builder builder() { |
| return new Builder() { |
| private double[] items = new double[0]; |
| |
| @Override |
| public void accept(double t) { |
| checkState(items != null, "Builder already built"); |
| items[items.length] = t; |
| } |
| |
| @Override |
| public DoubleStream build() { |
| checkState(items != null, "Builder already built"); |
| DoubleStream stream = Arrays.stream(items); |
| items = null; |
| return stream; |
| } |
| }; |
| } |
| |
| static DoubleStream concat(DoubleStream a, DoubleStream b) { |
| // This is nearly the same as flatMap, but inlined, wrapped around a single spliterator of |
| // these two objects, and without close() called as the stream progresses. Instead, close is |
| // invoked as part of the resulting stream's own onClose, so that either can fail without |
| // affecting the other, and correctly collecting suppressed exceptions. |
| |
| // TODO replace this flatMap-ish spliterator with one that directly combines the two root |
| // streams |
| Spliterator<? extends DoubleStream> spliteratorOfStreams = Arrays.asList(a, b).spliterator(); |
| |
| Spliterator.OfDouble spliterator = |
| new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE, 0) { |
| Spliterator.OfDouble next; |
| |
| @Override |
| public boolean tryAdvance(DoubleConsumer action) { |
| // look for a new spliterator |
| while (advanceToNextSpliterator()) { |
| // if we have one, try to read and use it |
| if (next.tryAdvance(action)) { |
| return true; |
| } else { |
| // failed, null it out so we can find another |
| next = null; |
| } |
| } |
| return false; |
| } |
| |
| private boolean advanceToNextSpliterator() { |
| while (next == null) { |
| if (!spliteratorOfStreams.tryAdvance( |
| n -> { |
| if (n != null) { |
| next = n.spliterator(); |
| } |
| })) { |
| return false; |
| } |
| } |
| return true; |
| } |
| }; |
| |
| DoubleStream result = new DoubleStreamImpl(null, spliterator); |
| |
| return result.onClose(a::close).onClose(b::close); |
| } |
| |
| static DoubleStream empty() { |
| return new DoubleStreamImpl.Empty(null); |
| } |
| |
| static DoubleStream generate(DoubleSupplier s) { |
| Spliterator.OfDouble spliterator = |
| new Spliterators.AbstractDoubleSpliterator( |
| Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED) { |
| @Override |
| public boolean tryAdvance(DoubleConsumer action) { |
| action.accept(s.getAsDouble()); |
| return true; |
| } |
| }; |
| |
| return StreamSupport.doubleStream(spliterator, false); |
| } |
| |
| static DoubleStream iterate(double seed, DoubleUnaryOperator f) { |
| Spliterator.OfDouble spliterator = |
| new Spliterators.AbstractDoubleSpliterator( |
| Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED) { |
| private double next = seed; |
| |
| @Override |
| public boolean tryAdvance(DoubleConsumer action) { |
| action.accept(next); |
| next = f.applyAsDouble(next); |
| return true; |
| } |
| }; |
| |
| return StreamSupport.doubleStream(spliterator, false); |
| } |
| |
| static DoubleStream of(double... values) { |
| return Arrays.stream(values); |
| } |
| |
| static DoubleStream of(double t) { |
| // TODO consider a splittable that returns only a single value |
| return of(new double[] {t}); |
| } |
| |
| boolean allMatch(DoublePredicate predicate); |
| |
| boolean anyMatch(DoublePredicate predicate); |
| |
| OptionalDouble average(); |
| |
| Stream<Double> boxed(); |
| |
| <R> R collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer<R, R> combiner); |
| |
| long count(); |
| |
| DoubleStream distinct(); |
| |
| DoubleStream filter(DoublePredicate predicate); |
| |
| OptionalDouble findAny(); |
| |
| OptionalDouble findFirst(); |
| |
| DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper); |
| |
| void forEach(DoubleConsumer action); |
| |
| void forEachOrdered(DoubleConsumer action); |
| |
| @Override |
| PrimitiveIterator.OfDouble iterator(); |
| |
| DoubleStream limit(long maxSize); |
| |
| DoubleStream map(DoubleUnaryOperator mapper); |
| |
| IntStream mapToInt(DoubleToIntFunction mapper); |
| |
| LongStream mapToLong(DoubleToLongFunction mapper); |
| |
| <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper); |
| |
| OptionalDouble max(); |
| |
| OptionalDouble min(); |
| |
| boolean noneMatch(DoublePredicate predicate); |
| |
| @Override |
| DoubleStream parallel(); |
| |
| DoubleStream peek(DoubleConsumer action); |
| |
| OptionalDouble reduce(DoubleBinaryOperator op); |
| |
| double reduce(double identity, DoubleBinaryOperator op); |
| |
| @Override |
| DoubleStream sequential(); |
| |
| DoubleStream skip(long n); |
| |
| DoubleStream sorted(); |
| |
| @Override |
| Spliterator.OfDouble spliterator(); |
| |
| double sum(); |
| |
| DoubleSummaryStatistics summaryStatistics(); |
| |
| double[] toArray(); |
| } |