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