@Beta
  public static <T, R> Stream<R> mapWithIndex(
      Stream<T> stream, FunctionWithIndex<? super T, ? extends R> function) {
    checkNotNull(stream);
    checkNotNull(function);
    boolean isParallel = stream.isParallel();
    Spliterator<T> fromSpliterator = stream.spliterator();

    if (!fromSpliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
      Iterator<T> fromIterator = Spliterators.iterator(fromSpliterator);
      return StreamSupport.stream(
              new AbstractSpliterator<R>(
                  fromSpliterator.estimateSize(),
                  fromSpliterator.characteristics() & (Spliterator.ORDERED | Spliterator.SIZED)) {
                long index = 0;

                @Override
                public boolean tryAdvance(Consumer<? super R> action) {
                  if (fromIterator.hasNext()) {
                    action.accept(function.apply(fromIterator.next(), index++));
                    return true;
                  }
                  return false;
                }
              },
              isParallel)
          .onClose(stream::close);
    }
    class Splitr extends MapWithIndexSpliterator<Spliterator<T>, R, Splitr> implements Consumer<T> {
      @Nullable T holder;

      Splitr(Spliterator<T> splitr, long index) {
        super(splitr, index);
      }

      @Override
      public void accept(@Nullable T t) {
        this.holder = t;
      }

      @Override
      public boolean tryAdvance(Consumer<? super R> action) {
        if (fromSpliterator.tryAdvance(this)) {
          try {
            action.accept(function.apply(holder, index++));
            return true;
          } finally {
            holder = null;
          }
        }
        return false;
      }

      @Override
      Splitr createSplit(Spliterator<T> from, long i) {
        return new Splitr(from, i);
      }
    }
    return StreamSupport.stream(new Splitr(fromSpliterator, 0), isParallel).onClose(stream::close);
  }
@Beta
  public static <T, R> Stream<R> mapWithIndex(
      Stream<T> stream, FunctionWithIndex<? super T, ? extends R> function) {
    checkNotNull(stream);
    checkNotNull(function);
    boolean isParallel = stream.isParallel();
    Spliterator<T> fromSpliterator = stream.spliterator();

    if (!fromSpliterator.hasCharacteristics(Spliterator.SUBSIZED)) {
      Iterator<T> fromIterator = Spliterators.iterator(fromSpliterator);
      return StreamSupport.stream(
              new AbstractSpliterator<R>(
                  fromSpliterator.estimateSize(),
                  fromSpliterator.characteristics() & (Spliterator.ORDERED | Spliterator.SIZED)) {
                long index = 0;

                @Override
                public boolean tryAdvance(Consumer<? super R> action) {
                  if (fromIterator.hasNext()) {
                    action.accept(function.apply(fromIterator.next(), index++));
                    return true;
                  }
                  return false;
                }
              },
              isParallel)
          .onClose(stream::close);
    }
    class Splitr extends MapWithIndexSpliterator<Spliterator<T>, R, Splitr> implements Consumer<T> {
      @Nullable T holder;

      Splitr(Spliterator<T> splitr, long index) {
        super(splitr, index);
      }

      @Override
      public void accept(@Nullable T t) {
        this.holder = t;
      }

      @Override
      public boolean tryAdvance(Consumer<? super R> action) {
        if (fromSpliterator.tryAdvance(this)) {
          try {
            action.accept(function.apply(holder, index++));
            return true;
          } finally {
            holder = null;
          }
        }
        return false;
      }

      @Override
      Splitr createSplit(Spliterator<T> from, long i) {
        return new Splitr(from, i);
      }
    }
    return StreamSupport.stream(new Splitr(fromSpliterator, 0), isParallel).onClose(stream::close);
  }
@ Beta public static < T , R > Stream < R > mapWithIndex ( Stream < T > stream , FunctionWithIndex < ? super T , ? extends R > function ) { checkNotNull ( stream ) ; checkNotNull ( function ) ; boolean isParallel = stream . isParallel ( ) ; Spliterator < T > fromSpliterator = stream . spliterator ( ) ; if ( ! fromSpliterator . hasCharacteristics ( Spliterator . SUBSIZED ) ) { Iterator < T > fromIterator = Spliterators . iterator ( fromSpliterator ) ; return StreamSupport . stream ( new AbstractSpliterator < R > ( fromSpliterator . estimateSize ( ) , fromSpliterator . characteristics ( ) & ( Spliterator . ORDERED | Spliterator . SIZED ) ) { long index = 0 ; @ Override public boolean tryAdvance ( Consumer < ? super R > action ) { if ( fromIterator . hasNext ( ) ) { action . accept ( function . apply ( fromIterator . next ( ) , index ++ ) ) ; return true ; } return false ; } } , isParallel ) . onClose ( stream :: close ) ; } class Splitr extends MapWithIndexSpliterator < Spliterator < T > , R , Splitr > implements Consumer < T > { @ Nullable T holder ; Splitr ( Spliterator < T > splitr , long index ) { super ( splitr , index ) ; } @ Override public void accept ( @ Nullable T t ) { this . holder = t ; } @ Override public boolean tryAdvance ( Consumer < ? super R > action ) { if ( fromSpliterator . tryAdvance ( this ) ) { try { action . accept ( function . apply ( holder , index ++ ) ) ; return true ; } finally { holder = null ; } } return false ; } @ Override Splitr createSplit ( Spliterator < T > from , long i ) { return new Splitr ( from , i ) ; } } return StreamSupport . stream ( new Splitr ( fromSpliterator , 0 ) , isParallel ) . onClose ( stream :: close ) ; }
Returns a stream consisting of the results of applying the given function to the elements of
{@code stream} and their indices in the stream. For example,

<pre>{@code
mapWithIndex(
Stream.of("a", "b", "c"),
(str, index) -> str + ":" + index)
}</pre>

<p>would return {@code Stream.of("a:0", "b:1", "c:2")}.

<p>The resulting stream is <a
href="http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html">efficiently splittable</a>
if and only if {@code stream} was efficiently splittable and its underlying spliterator
reported {@link Spliterator#SUBSIZED}. This is generally the case if the underlying stream
comes from a data structure supporting efficient indexed random access, typically an array or
list.

<p>The order of the resulting stream is defined if and only if the order of the original stream
was defined.
Returns a stream consisting of the results of applying the given function to the elements of { @code stream } and their indices in the stream . For example