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