/* * 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.Comparator; import java.util.IntSummaryStatistics; import java.util.OptionalDouble; import java.util.OptionalInt; import java.util.PrimitiveIterator; import java.util.Spliterator; import java.util.Spliterators; import java.util.Spliterators.AbstractIntSpliterator; import java.util.function.BiConsumer; import java.util.function.IntBinaryOperator; import java.util.function.IntConsumer; import java.util.function.IntFunction; import java.util.function.IntPredicate; import java.util.function.IntSupplier; import java.util.function.IntToDoubleFunction; import java.util.function.IntToLongFunction; import java.util.function.IntUnaryOperator; import java.util.function.ObjIntConsumer; import java.util.function.Supplier; /** * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.html"> * the official Java API doc</a> for details. */ public interface IntStream extends BaseStream<Integer, IntStream> { /** * See <a * href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/IntStream.Builder.html">the * official Java API doc</a> for details. */ interface Builder extends IntConsumer { @Override void accept(int t); default IntStream.Builder add(int t) { accept(t); return this; } IntStream build(); } static Builder builder() { return new Builder() { private int[] items = new int[0]; @Override public void accept(int t) { checkState(items != null, "Builder already built"); items[items.length] = t; } @Override public IntStream build() { checkState(items != null, "Builder already built"); IntStream stream = Arrays.stream(items); items = null; return stream; } }; } static IntStream concat(IntStream a, IntStream 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 IntStream> spliteratorOfStreams = Arrays.asList(a, b).spliterator(); Spliterator.OfInt spliterator = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE, 0) { Spliterator.OfInt next; @Override public boolean tryAdvance(IntConsumer 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; } }; IntStream result = new IntStreamImpl(null, spliterator); return result.onClose(a::close).onClose(b::close); } static IntStream empty() { return new IntStreamImpl.Empty(null); } static IntStream generate(final IntSupplier s) { AbstractIntSpliterator spliterator = new Spliterators.AbstractIntSpliterator( Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED) { @Override public boolean tryAdvance(IntConsumer action) { action.accept(s.getAsInt()); return true; } }; return StreamSupport.intStream(spliterator, false); } static IntStream iterate(int seed, IntUnaryOperator f) { AbstractIntSpliterator spliterator = new Spliterators.AbstractIntSpliterator( Long.MAX_VALUE, Spliterator.IMMUTABLE | Spliterator.ORDERED) { private int next = seed; @Override public boolean tryAdvance(IntConsumer action) { action.accept(next); next = f.applyAsInt(next); return true; } }; return StreamSupport.intStream(spliterator, false); } static IntStream of(int... values) { return Arrays.stream(values); } static IntStream of(int t) { // TODO consider a splittable that returns only a single value return of(new int[] {t}); } static IntStream range(int startInclusive, int endExclusive) { if (startInclusive >= endExclusive) { return empty(); } return rangeClosed(startInclusive, endExclusive - 1); } static IntStream rangeClosed(int startInclusive, int endInclusive) { if (startInclusive > endInclusive) { return empty(); } int count = endInclusive - startInclusive + 1; AbstractIntSpliterator spliterator = new Spliterators.AbstractIntSpliterator( count, Spliterator.IMMUTABLE | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED | Spliterator.SORTED | Spliterator.DISTINCT) { private int next = startInclusive; @Override public Comparator<? super Integer> getComparator() { return null; } @Override public boolean tryAdvance(IntConsumer action) { if (next <= endInclusive) { action.accept(next++); return true; } return false; } }; return StreamSupport.intStream(spliterator, false); } boolean allMatch(IntPredicate predicate); boolean anyMatch(IntPredicate predicate); DoubleStream asDoubleStream(); LongStream asLongStream(); OptionalDouble average(); Stream<Integer> boxed(); <R> R collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R, R> combiner); long count(); IntStream distinct(); IntStream filter(IntPredicate predicate); OptionalInt findAny(); OptionalInt findFirst(); IntStream flatMap(IntFunction<? extends IntStream> mapper); void forEach(IntConsumer action); void forEachOrdered(IntConsumer action); @Override PrimitiveIterator.OfInt iterator(); IntStream limit(long maxSize); IntStream map(IntUnaryOperator mapper); DoubleStream mapToDouble(IntToDoubleFunction mapper); LongStream mapToLong(IntToLongFunction mapper); <U> Stream<U> mapToObj(IntFunction<? extends U> mapper); OptionalInt max(); OptionalInt min(); boolean noneMatch(IntPredicate predicate); @Override IntStream parallel(); IntStream peek(IntConsumer action); OptionalInt reduce(IntBinaryOperator op); int reduce(int identity, IntBinaryOperator op); @Override IntStream sequential(); IntStream skip(long n); IntStream sorted(); @Override Spliterator.OfInt spliterator(); int sum(); IntSummaryStatistics summaryStatistics(); int[] toArray(); }