001/*
002 * Copyright (C) 2015 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License"); you
005 * may not use this file except in compliance with the License.  You may
006 * obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.  See the License for the specific language governing
014 * permissions and limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import static com.google.common.base.Preconditions.checkNotNull;
020import static com.google.common.collect.NullnessCasts.uncheckedCastNullableTToT;
021import static java.lang.Math.min;
022import static java.util.Objects.requireNonNull;
023
024import com.google.common.annotations.Beta;
025import com.google.common.annotations.GwtCompatible;
026import com.google.common.math.LongMath;
027import com.google.errorprone.annotations.InlineMe;
028import com.google.errorprone.annotations.InlineMeValidationDisabled;
029import java.util.ArrayDeque;
030import java.util.Collection;
031import java.util.Deque;
032import java.util.Iterator;
033import java.util.OptionalDouble;
034import java.util.OptionalInt;
035import java.util.OptionalLong;
036import java.util.PrimitiveIterator;
037import java.util.Spliterator;
038import java.util.Spliterators;
039import java.util.Spliterators.AbstractSpliterator;
040import java.util.function.BiConsumer;
041import java.util.function.BiFunction;
042import java.util.function.Consumer;
043import java.util.function.DoubleConsumer;
044import java.util.function.IntConsumer;
045import java.util.function.LongConsumer;
046import java.util.stream.BaseStream;
047import java.util.stream.DoubleStream;
048import java.util.stream.IntStream;
049import java.util.stream.LongStream;
050import java.util.stream.Stream;
051import java.util.stream.StreamSupport;
052import javax.annotation.CheckForNull;
053import org.checkerframework.checker.nullness.qual.Nullable;
054
055/**
056 * Static utility methods related to {@code Stream} instances.
057 *
058 * @since 33.4.0 (but since 21.0 in the JRE flavor)
059 */
060@GwtCompatible
061@SuppressWarnings("Java7ApiChecker")
062/*
063 * Users will use most of these methods only if they're already using Stream. For a few other
064 * methods, like stream(Iterable), we have to rely on users not to call them without library
065 * desugaring.
066 */
067@IgnoreJRERequirement
068public final class Streams {
069  /**
070   * Returns a sequential {@link Stream} of the contents of {@code iterable}, delegating to {@link
071   * Collection#stream} if possible.
072   */
073  public static <T extends @Nullable Object> Stream<T> stream(Iterable<T> iterable) {
074    return (iterable instanceof Collection)
075        ? ((Collection<T>) iterable).stream()
076        : StreamSupport.stream(iterable.spliterator(), false);
077  }
078
079  /**
080   * Returns {@link Collection#stream}.
081   *
082   * @deprecated There is no reason to use this; just invoke {@code collection.stream()} directly.
083   */
084  @Deprecated
085  @InlineMe(replacement = "collection.stream()")
086  public static <T extends @Nullable Object> Stream<T> stream(Collection<T> collection) {
087    return collection.stream();
088  }
089
090  /**
091   * Returns a sequential {@link Stream} of the remaining contents of {@code iterator}. Do not use
092   * {@code iterator} directly after passing it to this method.
093   */
094  public static <T extends @Nullable Object> Stream<T> stream(Iterator<T> iterator) {
095    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
096  }
097
098  /**
099   * If a value is present in {@code optional}, returns a stream containing only that element,
100   * otherwise returns an empty stream.
101   */
102  public static <T> Stream<T> stream(com.google.common.base.Optional<T> optional) {
103    return optional.isPresent() ? Stream.of(optional.get()) : Stream.empty();
104  }
105
106  /**
107   * If a value is present in {@code optional}, returns a stream containing only that element,
108   * otherwise returns an empty stream.
109   *
110   * <p><b>Java 9 users:</b> use {@code optional.stream()} instead.
111   */
112  @Beta
113  @InlineMe(replacement = "optional.stream()")
114  @InlineMeValidationDisabled("Java 9+ API only")
115  public static <T> Stream<T> stream(java.util.Optional<T> optional) {
116    return optional.isPresent() ? Stream.of(optional.get()) : Stream.empty();
117  }
118
119  /**
120   * If a value is present in {@code optional}, returns a stream containing only that element,
121   * otherwise returns an empty stream.
122   *
123   * <p><b>Java 9 users:</b> use {@code optional.stream()} instead.
124   */
125  @Beta
126  @InlineMe(replacement = "optional.stream()")
127  @InlineMeValidationDisabled("Java 9+ API only")
128  public static IntStream stream(OptionalInt optional) {
129    return optional.isPresent() ? IntStream.of(optional.getAsInt()) : IntStream.empty();
130  }
131
132  /**
133   * If a value is present in {@code optional}, returns a stream containing only that element,
134   * otherwise returns an empty stream.
135   *
136   * <p><b>Java 9 users:</b> use {@code optional.stream()} instead.
137   */
138  @Beta
139  @InlineMe(replacement = "optional.stream()")
140  @InlineMeValidationDisabled("Java 9+ API only")
141  public static LongStream stream(OptionalLong optional) {
142    return optional.isPresent() ? LongStream.of(optional.getAsLong()) : LongStream.empty();
143  }
144
145  /**
146   * If a value is present in {@code optional}, returns a stream containing only that element,
147   * otherwise returns an empty stream.
148   *
149   * <p><b>Java 9 users:</b> use {@code optional.stream()} instead.
150   */
151  @Beta
152  @InlineMe(replacement = "optional.stream()")
153  @InlineMeValidationDisabled("Java 9+ API only")
154  public static DoubleStream stream(OptionalDouble optional) {
155    return optional.isPresent() ? DoubleStream.of(optional.getAsDouble()) : DoubleStream.empty();
156  }
157
158  @SuppressWarnings("CatchingUnchecked") // sneaky checked exception
159  private static void closeAll(BaseStream<?, ?>[] toClose) {
160    // If one of the streams throws an exception, continue closing the others, then throw the
161    // exception later. If more than one stream throws an exception, the later ones are added to the
162    // first as suppressed exceptions. We don't catch Error on the grounds that it should be allowed
163    // to propagate immediately.
164    Exception exception = null;
165    for (BaseStream<?, ?> stream : toClose) {
166      try {
167        stream.close();
168      } catch (Exception e) { // sneaky checked exception
169        if (exception == null) {
170          exception = e;
171        } else {
172          exception.addSuppressed(e);
173        }
174      }
175    }
176    if (exception != null) {
177      // Normally this is a RuntimeException that doesn't need sneakyThrow.
178      // But theoretically we could see sneaky checked exception
179      sneakyThrow(exception);
180    }
181  }
182
183  /** Throws an undeclared checked exception. */
184  private static void sneakyThrow(Throwable t) {
185    class SneakyThrower<T extends Throwable> {
186      @SuppressWarnings("unchecked") // not really safe, but that's the point
187      void throwIt(Throwable t) throws T {
188        throw (T) t;
189      }
190    }
191    new SneakyThrower<Error>().throwIt(t);
192  }
193
194  /**
195   * Returns a {@link Stream} containing the elements of the first stream, followed by the elements
196   * of the second stream, and so on.
197   *
198   * <p>This is equivalent to {@code Stream.of(streams).flatMap(stream -> stream)}, but the returned
199   * stream may perform better.
200   *
201   * @see Stream#concat(Stream, Stream)
202   */
203  @SuppressWarnings("unchecked") // could probably be avoided with a forwarding Spliterator
204  @SafeVarargs
205  public static <T extends @Nullable Object> Stream<T> concat(Stream<? extends T>... streams) {
206    // TODO(lowasser): consider an implementation that can support SUBSIZED
207    boolean isParallel = false;
208    int characteristics = Spliterator.ORDERED | Spliterator.SIZED | Spliterator.NONNULL;
209    long estimatedSize = 0L;
210    ImmutableList.Builder<Spliterator<? extends T>> splitrsBuilder =
211        new ImmutableList.Builder<>(streams.length);
212    for (Stream<? extends T> stream : streams) {
213      isParallel |= stream.isParallel();
214      Spliterator<? extends T> splitr = stream.spliterator();
215      splitrsBuilder.add(splitr);
216      characteristics &= splitr.characteristics();
217      estimatedSize = LongMath.saturatedAdd(estimatedSize, splitr.estimateSize());
218    }
219    return StreamSupport.stream(
220            CollectSpliterators.flatMap(
221                splitrsBuilder.build().spliterator(),
222                splitr -> (Spliterator<T>) splitr,
223                characteristics,
224                estimatedSize),
225            isParallel)
226        .onClose(() -> closeAll(streams));
227  }
228
229  /**
230   * Returns an {@link IntStream} containing the elements of the first stream, followed by the
231   * elements of the second stream, and so on.
232   *
233   * <p>This is equivalent to {@code Stream.of(streams).flatMapToInt(stream -> stream)}, but the
234   * returned stream may perform better.
235   *
236   * @see IntStream#concat(IntStream, IntStream)
237   */
238  public static IntStream concat(IntStream... streams) {
239    boolean isParallel = false;
240    int characteristics = Spliterator.ORDERED | Spliterator.SIZED | Spliterator.NONNULL;
241    long estimatedSize = 0L;
242    ImmutableList.Builder<Spliterator.OfInt> splitrsBuilder =
243        new ImmutableList.Builder<>(streams.length);
244    for (IntStream stream : streams) {
245      isParallel |= stream.isParallel();
246      Spliterator.OfInt splitr = stream.spliterator();
247      splitrsBuilder.add(splitr);
248      characteristics &= splitr.characteristics();
249      estimatedSize = LongMath.saturatedAdd(estimatedSize, splitr.estimateSize());
250    }
251    return StreamSupport.intStream(
252            CollectSpliterators.flatMapToInt(
253                splitrsBuilder.build().spliterator(),
254                splitr -> splitr,
255                characteristics,
256                estimatedSize),
257            isParallel)
258        .onClose(() -> closeAll(streams));
259  }
260
261  /**
262   * Returns a {@link LongStream} containing the elements of the first stream, followed by the
263   * elements of the second stream, and so on.
264   *
265   * <p>This is equivalent to {@code Stream.of(streams).flatMapToLong(stream -> stream)}, but the
266   * returned stream may perform better.
267   *
268   * @see LongStream#concat(LongStream, LongStream)
269   */
270  public static LongStream concat(LongStream... streams) {
271    boolean isParallel = false;
272    int characteristics = Spliterator.ORDERED | Spliterator.SIZED | Spliterator.NONNULL;
273    long estimatedSize = 0L;
274    ImmutableList.Builder<Spliterator.OfLong> splitrsBuilder =
275        new ImmutableList.Builder<>(streams.length);
276    for (LongStream stream : streams) {
277      isParallel |= stream.isParallel();
278      Spliterator.OfLong splitr = stream.spliterator();
279      splitrsBuilder.add(splitr);
280      characteristics &= splitr.characteristics();
281      estimatedSize = LongMath.saturatedAdd(estimatedSize, splitr.estimateSize());
282    }
283    return StreamSupport.longStream(
284            CollectSpliterators.flatMapToLong(
285                splitrsBuilder.build().spliterator(),
286                splitr -> splitr,
287                characteristics,
288                estimatedSize),
289            isParallel)
290        .onClose(() -> closeAll(streams));
291  }
292
293  /**
294   * Returns a {@link DoubleStream} containing the elements of the first stream, followed by the
295   * elements of the second stream, and so on.
296   *
297   * <p>This is equivalent to {@code Stream.of(streams).flatMapToDouble(stream -> stream)}, but the
298   * returned stream may perform better.
299   *
300   * @see DoubleStream#concat(DoubleStream, DoubleStream)
301   */
302  public static DoubleStream concat(DoubleStream... streams) {
303    boolean isParallel = false;
304    int characteristics = Spliterator.ORDERED | Spliterator.SIZED | Spliterator.NONNULL;
305    long estimatedSize = 0L;
306    ImmutableList.Builder<Spliterator.OfDouble> splitrsBuilder =
307        new ImmutableList.Builder<>(streams.length);
308    for (DoubleStream stream : streams) {
309      isParallel |= stream.isParallel();
310      Spliterator.OfDouble splitr = stream.spliterator();
311      splitrsBuilder.add(splitr);
312      characteristics &= splitr.characteristics();
313      estimatedSize = LongMath.saturatedAdd(estimatedSize, splitr.estimateSize());
314    }
315    return StreamSupport.doubleStream(
316            CollectSpliterators.flatMapToDouble(
317                splitrsBuilder.build().spliterator(),
318                splitr -> splitr,
319                characteristics,
320                estimatedSize),
321            isParallel)
322        .onClose(() -> closeAll(streams));
323  }
324
325  /**
326   * Returns a stream in which each element is the result of passing the corresponding element of
327   * each of {@code streamA} and {@code streamB} to {@code function}.
328   *
329   * <p>For example:
330   *
331   * <pre>{@code
332   * Streams.zip(
333   *   Stream.of("foo1", "foo2", "foo3"),
334   *   Stream.of("bar1", "bar2"),
335   *   (arg1, arg2) -> arg1 + ":" + arg2)
336   * }</pre>
337   *
338   * <p>will return {@code Stream.of("foo1:bar1", "foo2:bar2")}.
339   *
340   * <p>The resulting stream will only be as long as the shorter of the two input streams; if one
341   * stream is longer, its extra elements will be ignored.
342   *
343   * <p>Note that if you are calling {@link Stream#forEach} on the resulting stream, you might want
344   * to consider using {@link #forEachPair} instead of this method.
345   *
346   * <p><b>Performance note:</b> The resulting stream is not <a
347   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>.
348   * This may harm parallel performance.
349   */
350  @Beta
351  public static <A extends @Nullable Object, B extends @Nullable Object, R extends @Nullable Object>
352      Stream<R> zip(
353          Stream<A> streamA, Stream<B> streamB, BiFunction<? super A, ? super B, R> function) {
354    checkNotNull(streamA);
355    checkNotNull(streamB);
356    checkNotNull(function);
357    boolean isParallel = streamA.isParallel() || streamB.isParallel(); // same as Stream.concat
358    Spliterator<A> splitrA = streamA.spliterator();
359    Spliterator<B> splitrB = streamB.spliterator();
360    int characteristics =
361        splitrA.characteristics()
362            & splitrB.characteristics()
363            & (Spliterator.SIZED | Spliterator.ORDERED);
364    Iterator<A> itrA = Spliterators.iterator(splitrA);
365    Iterator<B> itrB = Spliterators.iterator(splitrB);
366    return StreamSupport.stream(
367            new AbstractSpliterator<R>(
368                min(splitrA.estimateSize(), splitrB.estimateSize()), characteristics) {
369              @Override
370              public boolean tryAdvance(Consumer<? super R> action) {
371                if (itrA.hasNext() && itrB.hasNext()) {
372                  action.accept(function.apply(itrA.next(), itrB.next()));
373                  return true;
374                }
375                return false;
376              }
377            },
378            isParallel)
379        .onClose(streamA::close)
380        .onClose(streamB::close);
381  }
382
383  /**
384   * Invokes {@code consumer} once for each pair of <i>corresponding</i> elements in {@code streamA}
385   * and {@code streamB}. If one stream is longer than the other, the extra elements are silently
386   * ignored. Elements passed to the consumer are guaranteed to come from the same position in their
387   * respective source streams. For example:
388   *
389   * <pre>{@code
390   * Streams.forEachPair(
391   *   Stream.of("foo1", "foo2", "foo3"),
392   *   Stream.of("bar1", "bar2"),
393   *   (arg1, arg2) -> System.out.println(arg1 + ":" + arg2)
394   * }</pre>
395   *
396   * <p>will print:
397   *
398   * <pre>{@code
399   * foo1:bar1
400   * foo2:bar2
401   * }</pre>
402   *
403   * <p><b>Warning:</b> If either supplied stream is a parallel stream, the same correspondence
404   * between elements will be made, but the order in which those pairs of elements are passed to the
405   * consumer is <i>not</i> defined.
406   *
407   * <p>Note that many usages of this method can be replaced with simpler calls to {@link #zip}.
408   * This method behaves equivalently to {@linkplain #zip zipping} the stream elements into
409   * temporary pair objects and then using {@link Stream#forEach} on that stream.
410   *
411   * @since 33.4.0 (but since 22.0 in the JRE flavor)
412   */
413  @Beta
414  public static <A extends @Nullable Object, B extends @Nullable Object> void forEachPair(
415      Stream<A> streamA, Stream<B> streamB, BiConsumer<? super A, ? super B> consumer) {
416    checkNotNull(consumer);
417
418    if (streamA.isParallel() || streamB.isParallel()) {
419      zip(streamA, streamB, TemporaryPair::new).forEach(pair -> consumer.accept(pair.a, pair.b));
420    } else {
421      Iterator<A> iterA = streamA.iterator();
422      Iterator<B> iterB = streamB.iterator();
423      while (iterA.hasNext() && iterB.hasNext()) {
424        consumer.accept(iterA.next(), iterB.next());
425      }
426    }
427  }
428
429  // Use this carefully - it doesn't implement value semantics
430  private static class TemporaryPair<A extends @Nullable Object, B extends @Nullable Object> {
431    @ParametricNullness final A a;
432    @ParametricNullness final B b;
433
434    TemporaryPair(@ParametricNullness A a, @ParametricNullness B b) {
435      this.a = a;
436      this.b = b;
437    }
438  }
439
440  /**
441   * Returns a stream consisting of the results of applying the given function to the elements of
442   * {@code stream} and their indices in the stream. For example,
443   *
444   * <pre>{@code
445   * mapWithIndex(
446   *     Stream.of("a", "b", "c"),
447   *     (e, index) -> index + ":" + e)
448   * }</pre>
449   *
450   * <p>would return {@code Stream.of("0:a", "1:b", "2:c")}.
451   *
452   * <p>The resulting stream is <a
453   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
454   * if and only if {@code stream} was efficiently splittable and its underlying spliterator
455   * reported {@link Spliterator#SUBSIZED}. This is generally the case if the underlying stream
456   * comes from a data structure supporting efficient indexed random access, typically an array or
457   * list.
458   *
459   * <p>The order of the resulting stream is defined if and only if the order of the original stream
460   * was defined.
461   */
462  public static <T extends @Nullable Object, R extends @Nullable Object> Stream<R> mapWithIndex(
463      Stream<T> stream, FunctionWithIndex<? super T, ? extends R> function) {
464    checkNotNull(stream);
465    checkNotNull(function);
466    boolean isParallel = stream.isParallel();
467    Spliterator<T> fromSpliterator = stream.spliterator();
468
469    if (!fromSpliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
470      Iterator<T> fromIterator = Spliterators.iterator(fromSpliterator);
471      return StreamSupport.stream(
472              new AbstractSpliterator<R>(
473                  fromSpliterator.estimateSize(),
474                  fromSpliterator.characteristics() & (Spliterator.ORDERED | Spliterator.SIZED)) {
475                long index = 0;
476
477                @Override
478                public boolean tryAdvance(Consumer<? super R> action) {
479                  if (fromIterator.hasNext()) {
480                    action.accept(function.apply(fromIterator.next(), index++));
481                    return true;
482                  }
483                  return false;
484                }
485              },
486              isParallel)
487          .onClose(stream::close);
488    }
489    class Splitr extends MapWithIndexSpliterator<Spliterator<T>, R, Splitr> implements Consumer<T> {
490      @CheckForNull T holder;
491
492      Splitr(Spliterator<T> splitr, long index) {
493        super(splitr, index);
494      }
495
496      @Override
497      public void accept(@ParametricNullness T t) {
498        this.holder = t;
499      }
500
501      @Override
502      public boolean tryAdvance(Consumer<? super R> action) {
503        if (fromSpliterator.tryAdvance(this)) {
504          try {
505            // The cast is safe because tryAdvance puts a T into `holder`.
506            action.accept(function.apply(uncheckedCastNullableTToT(holder), index++));
507            return true;
508          } finally {
509            holder = null;
510          }
511        }
512        return false;
513      }
514
515      @Override
516      Splitr createSplit(Spliterator<T> from, long i) {
517        return new Splitr(from, i);
518      }
519    }
520    return StreamSupport.stream(new Splitr(fromSpliterator, 0), isParallel).onClose(stream::close);
521  }
522
523  /**
524   * Returns a stream consisting of the results of applying the given function to the elements of
525   * {@code stream} and their indexes in the stream. For example,
526   *
527   * <pre>{@code
528   * mapWithIndex(
529   *     IntStream.of(10, 11, 12),
530   *     (e, index) -> index + ":" + e)
531   * }</pre>
532   *
533   * <p>...would return {@code Stream.of("0:10", "1:11", "2:12")}.
534   *
535   * <p>The resulting stream is <a
536   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
537   * if and only if {@code stream} was efficiently splittable and its underlying spliterator
538   * reported {@link Spliterator#SUBSIZED}. This is generally the case if the underlying stream
539   * comes from a data structure supporting efficient indexed random access, typically an array or
540   * list.
541   *
542   * <p>The order of the resulting stream is defined if and only if the order of the original stream
543   * was defined.
544   */
545  @SuppressWarnings("AndroidJdkLibsChecker") // b/229998664
546  public static <R extends @Nullable Object> Stream<R> mapWithIndex(
547      IntStream stream, IntFunctionWithIndex<R> function) {
548    checkNotNull(stream);
549    checkNotNull(function);
550    boolean isParallel = stream.isParallel();
551    Spliterator.OfInt fromSpliterator = stream.spliterator();
552
553    if (!fromSpliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
554      PrimitiveIterator.OfInt fromIterator = Spliterators.iterator(fromSpliterator);
555      return StreamSupport.stream(
556              new AbstractSpliterator<R>(
557                  fromSpliterator.estimateSize(),
558                  fromSpliterator.characteristics() & (Spliterator.ORDERED | Spliterator.SIZED)) {
559                long index = 0;
560
561                @Override
562                public boolean tryAdvance(Consumer<? super R> action) {
563                  if (fromIterator.hasNext()) {
564                    action.accept(function.apply(fromIterator.nextInt(), index++));
565                    return true;
566                  }
567                  return false;
568                }
569              },
570              isParallel)
571          .onClose(stream::close);
572    }
573    class Splitr extends MapWithIndexSpliterator<Spliterator.OfInt, R, Splitr>
574        implements IntConsumer, Spliterator<R> {
575      int holder;
576
577      Splitr(Spliterator.OfInt splitr, long index) {
578        super(splitr, index);
579      }
580
581      @Override
582      public void accept(int t) {
583        this.holder = t;
584      }
585
586      @Override
587      public boolean tryAdvance(Consumer<? super R> action) {
588        if (fromSpliterator.tryAdvance(this)) {
589          action.accept(function.apply(holder, index++));
590          return true;
591        }
592        return false;
593      }
594
595      @Override
596      Splitr createSplit(Spliterator.OfInt from, long i) {
597        return new Splitr(from, i);
598      }
599    }
600    return StreamSupport.stream(new Splitr(fromSpliterator, 0), isParallel).onClose(stream::close);
601  }
602
603  /**
604   * Returns a stream consisting of the results of applying the given function to the elements of
605   * {@code stream} and their indexes in the stream. For example,
606   *
607   * <pre>{@code
608   * mapWithIndex(
609   *     LongStream.of(10, 11, 12),
610   *     (e, index) -> index + ":" + e)
611   * }</pre>
612   *
613   * <p>...would return {@code Stream.of("0:10", "1:11", "2:12")}.
614   *
615   * <p>The resulting stream is <a
616   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
617   * if and only if {@code stream} was efficiently splittable and its underlying spliterator
618   * reported {@link Spliterator#SUBSIZED}. This is generally the case if the underlying stream
619   * comes from a data structure supporting efficient indexed random access, typically an array or
620   * list.
621   *
622   * <p>The order of the resulting stream is defined if and only if the order of the original stream
623   * was defined.
624   */
625  @SuppressWarnings("AndroidJdkLibsChecker") // b/229998664
626  public static <R extends @Nullable Object> Stream<R> mapWithIndex(
627      LongStream stream, LongFunctionWithIndex<R> function) {
628    checkNotNull(stream);
629    checkNotNull(function);
630    boolean isParallel = stream.isParallel();
631    Spliterator.OfLong fromSpliterator = stream.spliterator();
632
633    if (!fromSpliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
634      PrimitiveIterator.OfLong fromIterator = Spliterators.iterator(fromSpliterator);
635      return StreamSupport.stream(
636              new AbstractSpliterator<R>(
637                  fromSpliterator.estimateSize(),
638                  fromSpliterator.characteristics() & (Spliterator.ORDERED | Spliterator.SIZED)) {
639                long index = 0;
640
641                @Override
642                public boolean tryAdvance(Consumer<? super R> action) {
643                  if (fromIterator.hasNext()) {
644                    action.accept(function.apply(fromIterator.nextLong(), index++));
645                    return true;
646                  }
647                  return false;
648                }
649              },
650              isParallel)
651          .onClose(stream::close);
652    }
653    class Splitr extends MapWithIndexSpliterator<Spliterator.OfLong, R, Splitr>
654        implements LongConsumer, Spliterator<R> {
655      long holder;
656
657      Splitr(Spliterator.OfLong splitr, long index) {
658        super(splitr, index);
659      }
660
661      @Override
662      public void accept(long t) {
663        this.holder = t;
664      }
665
666      @Override
667      public boolean tryAdvance(Consumer<? super R> action) {
668        if (fromSpliterator.tryAdvance(this)) {
669          action.accept(function.apply(holder, index++));
670          return true;
671        }
672        return false;
673      }
674
675      @Override
676      Splitr createSplit(Spliterator.OfLong from, long i) {
677        return new Splitr(from, i);
678      }
679    }
680    return StreamSupport.stream(new Splitr(fromSpliterator, 0), isParallel).onClose(stream::close);
681  }
682
683  /**
684   * Returns a stream consisting of the results of applying the given function to the elements of
685   * {@code stream} and their indexes in the stream. For example,
686   *
687   * <pre>{@code
688   * mapWithIndex(
689   *     DoubleStream.of(0.0, 1.0, 2.0)
690   *     (e, index) -> index + ":" + e)
691   * }</pre>
692   *
693   * <p>...would return {@code Stream.of("0:0.0", "1:1.0", "2:2.0")}.
694   *
695   * <p>The resulting stream is <a
696   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
697   * if and only if {@code stream} was efficiently splittable and its underlying spliterator
698   * reported {@link Spliterator#SUBSIZED}. This is generally the case if the underlying stream
699   * comes from a data structure supporting efficient indexed random access, typically an array or
700   * list.
701   *
702   * <p>The order of the resulting stream is defined if and only if the order of the original stream
703   * was defined.
704   */
705  @SuppressWarnings("AndroidJdkLibsChecker") // b/229998664
706  public static <R extends @Nullable Object> Stream<R> mapWithIndex(
707      DoubleStream stream, DoubleFunctionWithIndex<R> function) {
708    checkNotNull(stream);
709    checkNotNull(function);
710    boolean isParallel = stream.isParallel();
711    Spliterator.OfDouble fromSpliterator = stream.spliterator();
712
713    if (!fromSpliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
714      PrimitiveIterator.OfDouble fromIterator = Spliterators.iterator(fromSpliterator);
715      return StreamSupport.stream(
716              new AbstractSpliterator<R>(
717                  fromSpliterator.estimateSize(),
718                  fromSpliterator.characteristics() & (Spliterator.ORDERED | Spliterator.SIZED)) {
719                long index = 0;
720
721                @Override
722                public boolean tryAdvance(Consumer<? super R> action) {
723                  if (fromIterator.hasNext()) {
724                    action.accept(function.apply(fromIterator.nextDouble(), index++));
725                    return true;
726                  }
727                  return false;
728                }
729              },
730              isParallel)
731          .onClose(stream::close);
732    }
733    class Splitr extends MapWithIndexSpliterator<Spliterator.OfDouble, R, Splitr>
734        implements DoubleConsumer, Spliterator<R> {
735      double holder;
736
737      Splitr(Spliterator.OfDouble splitr, long index) {
738        super(splitr, index);
739      }
740
741      @Override
742      public void accept(double t) {
743        this.holder = t;
744      }
745
746      @Override
747      public boolean tryAdvance(Consumer<? super R> action) {
748        if (fromSpliterator.tryAdvance(this)) {
749          action.accept(function.apply(holder, index++));
750          return true;
751        }
752        return false;
753      }
754
755      @Override
756      Splitr createSplit(Spliterator.OfDouble from, long i) {
757        return new Splitr(from, i);
758      }
759    }
760    return StreamSupport.stream(new Splitr(fromSpliterator, 0), isParallel).onClose(stream::close);
761  }
762
763  /**
764   * An analogue of {@link java.util.function.Function} also accepting an index.
765   *
766   * <p>This interface is only intended for use by callers of {@link #mapWithIndex(Stream,
767   * FunctionWithIndex)}.
768   *
769   * @since 33.4.0 (but since 21.0 in the JRE flavor)
770   */
771  public interface FunctionWithIndex<T extends @Nullable Object, R extends @Nullable Object> {
772    /** Applies this function to the given argument and its index within a stream. */
773    @ParametricNullness
774    R apply(@ParametricNullness T from, long index);
775  }
776
777  /*
778   * @IgnoreJRERequirement should be redundant with the one on Streams itself, but it's necessary as
779   * of Animal Sniffer 1.24. Maybe Animal Sniffer processes this nested class before it processes
780   * Streams and thus hasn't had a chance to see Streams's annotation?
781   */
782  @IgnoreJRERequirement
783  private abstract static class MapWithIndexSpliterator<
784          F extends Spliterator<?>,
785          R extends @Nullable Object,
786          S extends MapWithIndexSpliterator<F, R, S>>
787      implements Spliterator<R> {
788    final F fromSpliterator;
789    long index;
790
791    MapWithIndexSpliterator(F fromSpliterator, long index) {
792      this.fromSpliterator = fromSpliterator;
793      this.index = index;
794    }
795
796    abstract S createSplit(F from, long i);
797
798    @Override
799    @CheckForNull
800    public S trySplit() {
801      Spliterator<?> splitOrNull = fromSpliterator.trySplit();
802      if (splitOrNull == null) {
803        return null;
804      }
805      @SuppressWarnings("unchecked")
806      F split = (F) splitOrNull;
807      S result = createSplit(split, index);
808      this.index += split.getExactSizeIfKnown();
809      return result;
810    }
811
812    @Override
813    public long estimateSize() {
814      return fromSpliterator.estimateSize();
815    }
816
817    @Override
818    public int characteristics() {
819      return fromSpliterator.characteristics()
820          & (Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED);
821    }
822  }
823
824  /**
825   * An analogue of {@link java.util.function.IntFunction} also accepting an index.
826   *
827   * <p>This interface is only intended for use by callers of {@link #mapWithIndex(IntStream,
828   * IntFunctionWithIndex)}.
829   *
830   * @since 33.4.0 (but since 21.0 in the JRE flavor)
831   */
832  public interface IntFunctionWithIndex<R extends @Nullable Object> {
833    /** Applies this function to the given argument and its index within a stream. */
834    @ParametricNullness
835    R apply(int from, long index);
836  }
837
838  /**
839   * An analogue of {@link java.util.function.LongFunction} also accepting an index.
840   *
841   * <p>This interface is only intended for use by callers of {@link #mapWithIndex(LongStream,
842   * LongFunctionWithIndex)}.
843   *
844   * @since 33.4.0 (but since 21.0 in the JRE flavor)
845   */
846  public interface LongFunctionWithIndex<R extends @Nullable Object> {
847    /** Applies this function to the given argument and its index within a stream. */
848    @ParametricNullness
849    R apply(long from, long index);
850  }
851
852  /**
853   * An analogue of {@link java.util.function.DoubleFunction} also accepting an index.
854   *
855   * <p>This interface is only intended for use by callers of {@link #mapWithIndex(DoubleStream,
856   * DoubleFunctionWithIndex)}.
857   *
858   * @since 33.4.0 (but since 21.0 in the JRE flavor)
859   */
860  public interface DoubleFunctionWithIndex<R extends @Nullable Object> {
861    /** Applies this function to the given argument and its index within a stream. */
862    @ParametricNullness
863    R apply(double from, long index);
864  }
865
866  /**
867   * Returns the last element of the specified stream, or {@link java.util.Optional#empty} if the
868   * stream is empty.
869   *
870   * <p>Equivalent to {@code stream.reduce((a, b) -> b)}, but may perform significantly better. This
871   * method's runtime will be between O(log n) and O(n), performing better on <a
872   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
873   * streams.
874   *
875   * <p>If the stream has nondeterministic order, this has equivalent semantics to {@link
876   * Stream#findAny} (which you might as well use).
877   *
878   * @see Stream#findFirst()
879   * @throws NullPointerException if the last element of the stream is null
880   */
881  /*
882   * By declaring <T> instead of <T extends @Nullable Object>, we declare this method as requiring a
883   * stream whose elements are non-null. However, the method goes out of its way to still handle
884   * nulls in the stream. This means that the method can safely be used with a stream that contains
885   * nulls as long as the *last* element is *not* null.
886   *
887   * (To "go out of its way," the method tracks a `set` bit so that it can distinguish "the final
888   * split has a last element of null, so throw NPE" from "the final split was empty, so look for an
889   * element in the prior one.")
890   */
891  public static <T> java.util.Optional<T> findLast(Stream<T> stream) {
892    class OptionalState {
893      boolean set = false;
894      @CheckForNull T value = null;
895
896      void set(T value) {
897        this.set = true;
898        this.value = value;
899      }
900
901      T get() {
902        /*
903         * requireNonNull is safe because we call get() only if we've previously called set().
904         *
905         * (For further discussion of nullness, see the comment above the method.)
906         */
907        return requireNonNull(value);
908      }
909    }
910    OptionalState state = new OptionalState();
911
912    Deque<Spliterator<T>> splits = new ArrayDeque<>();
913    splits.addLast(stream.spliterator());
914
915    while (!splits.isEmpty()) {
916      Spliterator<T> spliterator = splits.removeLast();
917
918      if (spliterator.getExactSizeIfKnown() == 0) {
919        continue; // drop this split
920      }
921
922      // Many spliterators will have trySplits that are SUBSIZED even if they are not themselves
923      // SUBSIZED.
924      if (spliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
925        // we can drill down to exactly the smallest nonempty spliterator
926        while (true) {
927          Spliterator<T> prefix = spliterator.trySplit();
928          if (prefix == null || prefix.getExactSizeIfKnown() == 0) {
929            break;
930          } else if (spliterator.getExactSizeIfKnown() == 0) {
931            spliterator = prefix;
932            break;
933          }
934        }
935
936        // spliterator is known to be nonempty now
937        spliterator.forEachRemaining(state::set);
938        return java.util.Optional.of(state.get());
939      }
940
941      Spliterator<T> prefix = spliterator.trySplit();
942      if (prefix == null || prefix.getExactSizeIfKnown() == 0) {
943        // we can't split this any further
944        spliterator.forEachRemaining(state::set);
945        if (state.set) {
946          return java.util.Optional.of(state.get());
947        }
948        // fall back to the last split
949        continue;
950      }
951      splits.addLast(prefix);
952      splits.addLast(spliterator);
953    }
954    return java.util.Optional.empty();
955  }
956
957  /**
958   * Returns the last element of the specified stream, or {@link OptionalInt#empty} if the stream is
959   * empty.
960   *
961   * <p>Equivalent to {@code stream.reduce((a, b) -> b)}, but may perform significantly better. This
962   * method's runtime will be between O(log n) and O(n), performing better on <a
963   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
964   * streams.
965   *
966   * @see IntStream#findFirst()
967   * @throws NullPointerException if the last element of the stream is null
968   */
969  public static OptionalInt findLast(IntStream stream) {
970    // findLast(Stream) does some allocation, so we might as well box some more
971    java.util.Optional<Integer> boxedLast = findLast(stream.boxed());
972    return boxedLast.map(OptionalInt::of).orElse(OptionalInt.empty());
973  }
974
975  /**
976   * Returns the last element of the specified stream, or {@link OptionalLong#empty} if the stream
977   * is empty.
978   *
979   * <p>Equivalent to {@code stream.reduce((a, b) -> b)}, but may perform significantly better. This
980   * method's runtime will be between O(log n) and O(n), performing better on <a
981   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
982   * streams.
983   *
984   * @see LongStream#findFirst()
985   * @throws NullPointerException if the last element of the stream is null
986   */
987  public static OptionalLong findLast(LongStream stream) {
988    // findLast(Stream) does some allocation, so we might as well box some more
989    java.util.Optional<Long> boxedLast = findLast(stream.boxed());
990    return boxedLast.map(OptionalLong::of).orElse(OptionalLong.empty());
991  }
992
993  /**
994   * Returns the last element of the specified stream, or {@link OptionalDouble#empty} if the stream
995   * is empty.
996   *
997   * <p>Equivalent to {@code stream.reduce((a, b) -> b)}, but may perform significantly better. This
998   * method's runtime will be between O(log n) and O(n), performing better on <a
999   * href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
1000   * streams.
1001   *
1002   * @see DoubleStream#findFirst()
1003   * @throws NullPointerException if the last element of the stream is null
1004   */
1005  public static OptionalDouble findLast(DoubleStream stream) {
1006    // findLast(Stream) does some allocation, so we might as well box some more
1007    java.util.Optional<Double> boxedLast = findLast(stream.boxed());
1008    return boxedLast.map(OptionalDouble::of).orElse(OptionalDouble.empty());
1009  }
1010
1011  private Streams() {}
1012}