| /* |
| * 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(); |
| } |