001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3.stream; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.Collections; 022import java.util.Enumeration; 023import java.util.Iterator; 024import java.util.List; 025import java.util.Objects; 026import java.util.Set; 027import java.util.Spliterator; 028import java.util.Spliterators; 029import java.util.Spliterators.AbstractSpliterator; 030import java.util.function.BiConsumer; 031import java.util.function.BinaryOperator; 032import java.util.function.Consumer; 033import java.util.function.Function; 034import java.util.function.Predicate; 035import java.util.function.Supplier; 036import java.util.stream.Collector; 037import java.util.stream.Collectors; 038import java.util.stream.Stream; 039import java.util.stream.StreamSupport; 040 041import org.apache.commons.lang3.ArrayUtils; 042import org.apache.commons.lang3.function.Failable; 043import org.apache.commons.lang3.function.FailableConsumer; 044import org.apache.commons.lang3.function.FailableFunction; 045import org.apache.commons.lang3.function.FailablePredicate; 046 047/** 048 * Provides utility functions, and classes for working with the {@link java.util.stream} package, or more generally, with Java 8 lambdas. More specifically, it 049 * attempts to address the fact that lambdas are supposed not to throw Exceptions, at least not checked Exceptions, AKA instances of {@link Exception}. This 050 * enforces the use of constructs like: 051 * 052 * <pre>{@code 053 * Consumer<java.lang.reflect.Method> consumer = m -> { 054 * try { 055 * m.invoke(o, args); 056 * } catch (Throwable t) { 057 * throw Failable.rethrow(t); 058 * } 059 * }; 060 * stream.forEach(consumer); 061 * }</pre> 062 * <p> 063 * Using a {@link FailableStream}, this can be rewritten as follows: 064 * </p> 065 * 066 * <pre>{@code 067 * Streams.failable(stream).forEach(m -> m.invoke(o, args)); 068 * }</pre> 069 * <p> 070 * Obviously, the second version is much more concise and the spirit of Lambda expressions is met better than in the first version. 071 * </p> 072 * 073 * @see Stream 074 * @see Failable 075 * @since 3.11 076 */ 077public class Streams { 078 079 /** 080 * A Collector type for arrays. 081 * 082 * @param <E> The array type. 083 */ 084 public static class ArrayCollector<E> implements Collector<E, List<E>, E[]> { 085 private static final Set<Characteristics> characteristics = Collections.emptySet(); 086 private final Class<E> elementType; 087 088 /** 089 * Constructs a new instance for the given element type. 090 * 091 * @param elementType The element type. 092 */ 093 public ArrayCollector(final Class<E> elementType) { 094 this.elementType = Objects.requireNonNull(elementType, "elementType"); 095 } 096 097 @Override 098 public BiConsumer<List<E>, E> accumulator() { 099 return List::add; 100 } 101 102 @Override 103 public Set<Characteristics> characteristics() { 104 return characteristics; 105 } 106 107 @Override 108 public BinaryOperator<List<E>> combiner() { 109 return (left, right) -> { 110 left.addAll(right); 111 return left; 112 }; 113 } 114 115 @Override 116 public Function<List<E>, E[]> finisher() { 117 return list -> list.toArray(ArrayUtils.newInstance(elementType, list.size())); 118 } 119 120 @Override 121 public Supplier<List<E>> supplier() { 122 return ArrayList::new; 123 } 124 } 125 126 /** 127 * Helps implement {@link Streams#of(Enumeration)}. 128 * 129 * @param <T> The element type. 130 */ 131 private static final class EnumerationSpliterator<T> extends AbstractSpliterator<T> { 132 133 private final Enumeration<T> enumeration; 134 135 /** 136 * Creates a spliterator reporting the given estimated size and additionalCharacteristics. 137 * 138 * @param estimatedSize the estimated size of this spliterator if known, otherwise {@code Long.MAX_VALUE}. 139 * @param additionalCharacteristics properties of this spliterator's source or elements. If {@code SIZED} is reported then this spliterator will 140 * additionally report {@code SUBSIZED}. 141 * @param enumeration The Enumeration to wrap. 142 */ 143 protected EnumerationSpliterator(final long estimatedSize, final int additionalCharacteristics, final Enumeration<T> enumeration) { 144 super(estimatedSize, additionalCharacteristics); 145 this.enumeration = Objects.requireNonNull(enumeration, "enumeration"); 146 } 147 148 @Override 149 public void forEachRemaining(final Consumer<? super T> action) { 150 while (enumeration.hasMoreElements()) { 151 next(action); 152 } 153 } 154 155 private boolean next(final Consumer<? super T> action) { 156 action.accept(enumeration.nextElement()); 157 return true; 158 159 } 160 161 @Override 162 public boolean tryAdvance(final Consumer<? super T> action) { 163 return enumeration.hasMoreElements() && next(action); 164 } 165 } 166 167 /** 168 * A reduced, and simplified version of a {@link Stream} with failable method signatures. 169 * 170 * @param <T> The streams element type. 171 */ 172 public static class FailableStream<T> { 173 174 private Stream<T> stream; 175 private boolean terminated; 176 177 /** 178 * Constructs a new instance with the given {@code stream}. 179 * 180 * @param stream The stream. 181 */ 182 public FailableStream(final Stream<T> stream) { 183 this.stream = stream; 184 } 185 186 /** 187 * Returns whether all elements of this stream match the provided predicate. May not evaluate the predicate on all 188 * elements if not necessary for determining the result. If the stream is empty then {@code true} is returned and the 189 * predicate is not evaluated. 190 * 191 * <p> 192 * This is a short-circuiting terminal operation. 193 * </p> 194 * 195 * Note This method evaluates the <em>universal quantification</em> of the predicate over the elements of the stream 196 * (for all x P(x)). If the stream is empty, the quantification is said to be <em>vacuously satisfied</em> and is always 197 * {@code true} (regardless of P(x)). 198 * 199 * @param predicate A non-interfering, stateless predicate to apply to elements of this stream 200 * @return {@code true} If either all elements of the stream match the provided predicate or the stream is empty, 201 * otherwise {@code false}. 202 */ 203 public boolean allMatch(final FailablePredicate<T, ?> predicate) { 204 assertNotTerminated(); 205 return stream().allMatch(Failable.asPredicate(predicate)); 206 } 207 208 /** 209 * Returns whether any elements of this stream match the provided predicate. May not evaluate the predicate on all 210 * elements if not necessary for determining the result. If the stream is empty then {@code false} is returned and the 211 * predicate is not evaluated. 212 * 213 * <p> 214 * This is a short-circuiting terminal operation. 215 * </p> 216 * 217 * Note This method evaluates the <em>existential quantification</em> of the predicate over the elements of the stream 218 * (for some x P(x)). 219 * 220 * @param predicate A non-interfering, stateless predicate to apply to elements of this stream 221 * @return {@code true} if any elements of the stream match the provided predicate, otherwise {@code false} 222 */ 223 public boolean anyMatch(final FailablePredicate<T, ?> predicate) { 224 assertNotTerminated(); 225 return stream().anyMatch(Failable.asPredicate(predicate)); 226 } 227 228 /** 229 * Throws IllegalStateException if this stream is already terminated. 230 * 231 * @throws IllegalStateException if this stream is already terminated. 232 */ 233 protected void assertNotTerminated() { 234 if (terminated) { 235 throw new IllegalStateException("This stream is already terminated."); 236 } 237 } 238 239 /** 240 * Performs a mutable reduction operation on the elements of this stream using a {@link Collector}. A {@link Collector} 241 * encapsulates the functions used as arguments to {@link #collect(Supplier, BiConsumer, BiConsumer)}, allowing for 242 * reuse of collection strategies and composition of collect operations such as multiple-level grouping or partitioning. 243 * 244 * <p> 245 * If the underlying stream is parallel, and the {@link Collector} is concurrent, and either the stream is unordered or 246 * the collector is unordered, then a concurrent reduction will be performed (see {@link Collector} for details on 247 * concurrent reduction.) 248 * </p> 249 * 250 * <p> 251 * This is a terminal operation. 252 * </p> 253 * 254 * <p> 255 * When executed in parallel, multiple intermediate results may be instantiated, populated, and merged so as to maintain 256 * isolation of mutable data structures. Therefore, even when executed in parallel with non-thread-safe data structures 257 * (such as {@link ArrayList}), no additional synchronization is needed for a parallel reduction. 258 * </p> 259 * 260 * Note The following will accumulate strings into an ArrayList: 261 * 262 * <pre> 263 * {@code 264 * List<String> asList = stringStream.collect(Collectors.toList()); 265 * } 266 * </pre> 267 * 268 * <p> 269 * The following will classify {@code Person} objects by city: 270 * </p> 271 * 272 * <pre> 273 * {@code 274 * Map<String, List<Person>> peopleByCity = personStream.collect(Collectors.groupingBy(Person::getCity)); 275 * } 276 * </pre> 277 * 278 * <p> 279 * The following will classify {@code Person} objects by state and city, cascading two {@link Collector}s together: 280 * </p> 281 * 282 * <pre> 283 * {@code 284 * Map<String, Map<String, List<Person>>> peopleByStateAndCity = personStream 285 * .collect(Collectors.groupingBy(Person::getState, Collectors.groupingBy(Person::getCity))); 286 * } 287 * </pre> 288 * 289 * @param <R> the type of the result 290 * @param <A> the intermediate accumulation type of the {@link Collector} 291 * @param collector the {@link Collector} describing the reduction 292 * @return the result of the reduction 293 * @see #collect(Supplier, BiConsumer, BiConsumer) 294 * @see Collectors 295 */ 296 public <A, R> R collect(final Collector<? super T, A, R> collector) { 297 makeTerminated(); 298 return stream().collect(collector); 299 } 300 301 /** 302 * Performs a mutable reduction operation on the elements of this FailableStream. A mutable reduction is one in which 303 * the reduced value is a mutable result container, such as an {@link ArrayList}, and elements are incorporated by 304 * updating the state of the result rather than by replacing the result. This produces a result equivalent to: 305 * <pre> 306 * {@code 307 * R result = supplier.get(); 308 * for (T element : this stream) 309 * accumulator.accept(result, element); 310 * return result; 311 * } 312 * </pre> 313 * <p> 314 * Like {@link #reduce(Object, BinaryOperator)}, {@code collect} operations can be parallelized without requiring 315 * additional synchronization. 316 * </p> 317 * <p> 318 * This is a terminal operation. 319 * </p> 320 * <p> 321 * Note There are many existing classes in the JDK whose signatures are well-suited for use with method references as 322 * arguments to {@code collect()}. For example, the following will accumulate strings into an {@link ArrayList}: 323 * </p> 324 * <pre> 325 * {@code 326 * List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); 327 * } 328 * </pre> 329 * <p> 330 * The following will take a stream of strings and concatenates them into a single string: 331 * </p> 332 * <pre> 333 * {@code 334 * String concat = stringStream.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString(); 335 * } 336 * </pre> 337 * 338 * @param <R> type of the result 339 * @param <A> Type of the accumulator. 340 * @param supplier a function that creates a new result container. For a parallel execution, this function may be called 341 * multiple times and must return a fresh value each time. 342 * @param accumulator An associative, non-interfering, stateless function for incorporating an additional element into a 343 * result 344 * @param combiner An associative, non-interfering, stateless function for combining two values, which must be 345 * compatible with the accumulator function 346 * @return The result of the reduction 347 */ 348 public <A, R> R collect(final Supplier<R> supplier, final BiConsumer<R, ? super T> accumulator, final BiConsumer<R, R> combiner) { 349 makeTerminated(); 350 return stream().collect(supplier, accumulator, combiner); 351 } 352 353 /** 354 * Returns a FailableStream consisting of the elements of this stream that match the given FailablePredicate. 355 * <p> 356 * This is an intermediate operation. 357 * </p> 358 * 359 * @param predicate a non-interfering, stateless predicate to apply to each element to determine if it should be 360 * included. 361 * @return the new stream 362 */ 363 public FailableStream<T> filter(final FailablePredicate<T, ?> predicate) { 364 assertNotTerminated(); 365 stream = stream.filter(Failable.asPredicate(predicate)); 366 return this; 367 } 368 369 /** 370 * Performs an action for each element of this stream. 371 * <p> 372 * This is a terminal operation. 373 * </p> 374 * <p> 375 * The behavior of this operation is explicitly nondeterministic. For parallel stream pipelines, this operation does 376 * <em>not</em> guarantee to respect the encounter order of the stream, as doing so would sacrifice the benefit of 377 * parallelism. For any given element, the action may be performed at whatever time and in whatever thread the library 378 * chooses. If the action accesses shared state, it is responsible for providing the required synchronization. 379 * </p> 380 * 381 * @param action a non-interfering action to perform on the elements 382 */ 383 public void forEach(final FailableConsumer<T, ?> action) { 384 makeTerminated(); 385 stream().forEach(Failable.asConsumer(action)); 386 } 387 388 /** 389 * Marks this stream as terminated. 390 * 391 * @throws IllegalStateException if this stream is already terminated. 392 */ 393 protected void makeTerminated() { 394 assertNotTerminated(); 395 terminated = true; 396 } 397 398 /** 399 * Returns a stream consisting of the results of applying the given function to the elements of this stream. 400 * 401 * <p> 402 * This is an intermediate operation. 403 * </p> 404 * 405 * @param <R> The element type of the new stream 406 * @param mapper A non-interfering, stateless function to apply to each element 407 * @return the new stream 408 */ 409 public <R> FailableStream<R> map(final FailableFunction<T, R, ?> mapper) { 410 assertNotTerminated(); 411 return new FailableStream<>(stream.map(Failable.asFunction(mapper))); 412 } 413 414 /** 415 * Performs a reduction on the elements of this stream, using the provided identity value and an associative 416 * accumulation function, and returns the reduced value. This is equivalent to: 417 * 418 * <pre> 419 * {@code 420 * T result = identity; 421 * for (T element : this stream) 422 * result = accumulator.apply(result, element) 423 * return result; 424 * } 425 * </pre> 426 * 427 * but is not constrained to execute sequentially. 428 * 429 * <p> 430 * The {@code identity} value must be an identity for the accumulator function. This means that for all {@code t}, 431 * {@code accumulator.apply(identity, t)} is equal to {@code t}. The {@code accumulator} function must be an associative 432 * function. 433 * </p> 434 * 435 * <p> 436 * This is a terminal operation. 437 * </p> 438 * 439 * Note Sum, min, max, average, and string concatenation are all special cases of reduction. Summing a stream of numbers 440 * can be expressed as: 441 * 442 * <pre> 443 * {@code 444 * Integer sum = integers.reduce(0, (a, b) -> a + b); 445 * } 446 * </pre> 447 * 448 * or: 449 * 450 * <pre> 451 * {@code 452 * Integer sum = integers.reduce(0, Integer::sum); 453 * } 454 * </pre> 455 * 456 * <p> 457 * While this may seem a more roundabout way to perform an aggregation compared to simply mutating a running total in a 458 * loop, reduction operations parallelize more gracefully, without needing additional synchronization and with greatly 459 * reduced risk of data races. 460 * </p> 461 * 462 * @param identity the identity value for the accumulating function 463 * @param accumulator an associative, non-interfering, stateless function for combining two values 464 * @return the result of the reduction 465 */ 466 public T reduce(final T identity, final BinaryOperator<T> accumulator) { 467 makeTerminated(); 468 return stream().reduce(identity, accumulator); 469 } 470 471 /** 472 * Converts the FailableStream into an equivalent stream. 473 * 474 * @return A stream, which will return the same elements, which this FailableStream would return. 475 */ 476 public Stream<T> stream() { 477 return stream; 478 } 479 } 480 481 /** 482 * Converts the given {@link Collection} into a {@link FailableStream}. This is basically a simplified, reduced version 483 * of the {@link Stream} class, with the same underlying element stream, except that failable objects, like 484 * {@link FailablePredicate}, {@link FailableFunction}, or {@link FailableConsumer} may be applied, instead of 485 * {@link Predicate}, {@link Function}, or {@link Consumer}. The idea is to rewrite a code snippet like this: 486 * 487 * <pre> 488 * {@code 489 * final List<O> list; 490 * final Method m; 491 * final Function<O, String> mapper = (o) -> { 492 * try { 493 * return (String) m.invoke(o); 494 * } catch (Throwable t) { 495 * throw Failable.rethrow(t); 496 * } 497 * }; 498 * final List<String> strList = list.stream().map(mapper).collect(Collectors.toList()); 499 * } 500 * </pre> 501 * 502 * as follows: 503 * 504 * <pre> 505 * {@code 506 * final List<O> list; 507 * final Method m; 508 * final List<String> strList = Failable.stream(list.stream()).map((o) -> (String) m.invoke(o)).collect(Collectors.toList()); 509 * } 510 * </pre> 511 * 512 * While the second version may not be <em>quite</em> as efficient (because it depends on the creation of additional, 513 * intermediate objects, of type FailableStream), it is much more concise, and readable, and meets the spirit of Lambdas 514 * better than the first version. 515 * 516 * @param <T> The streams element type. 517 * @param stream The stream, which is being converted. 518 * @return The {@link FailableStream}, which has been created by converting the stream. 519 * @since 3.13.0 520 */ 521 public static <T> FailableStream<T> failableStream(final Collection<T> stream) { 522 return failableStream(of(stream)); 523 } 524 525 /** 526 * Converts the given {@link Stream stream} into a {@link FailableStream}. This is basically a simplified, reduced 527 * version of the {@link Stream} class, with the same underlying element stream, except that failable objects, like 528 * {@link FailablePredicate}, {@link FailableFunction}, or {@link FailableConsumer} may be applied, instead of 529 * {@link Predicate}, {@link Function}, or {@link Consumer}. The idea is to rewrite a code snippet like this: 530 * 531 * <pre> 532 * {@code 533 * final List<O> list; 534 * final Method m; 535 * final Function<O, String> mapper = (o) -> { 536 * try { 537 * return (String) m.invoke(o); 538 * } catch (Throwable t) { 539 * throw Failable.rethrow(t); 540 * } 541 * }; 542 * final List<String> strList = list.stream().map(mapper).collect(Collectors.toList()); 543 * } 544 * </pre> 545 * 546 * as follows: 547 * 548 * <pre> 549 * {@code 550 * final List<O> list; 551 * final Method m; 552 * final List<String> strList = Failable.stream(list.stream()).map((o) -> (String) m.invoke(o)).collect(Collectors.toList()); 553 * } 554 * </pre> 555 * 556 * While the second version may not be <em>quite</em> as efficient (because it depends on the creation of additional, 557 * intermediate objects, of type FailableStream), it is much more concise, and readable, and meets the spirit of Lambdas 558 * better than the first version. 559 * 560 * @param <T> The streams element type. 561 * @param stream The stream, which is being converted. 562 * @return The {@link FailableStream}, which has been created by converting the stream. 563 * @since 3.13.0 564 */ 565 public static <T> FailableStream<T> failableStream(final Stream<T> stream) { 566 return new FailableStream<>(stream); 567 } 568 569 /** 570 * Shorthand for {@code Streams.failableStream(value == null ? Stream.empty() : Stream.of(value))}. 571 * 572 * @param <T> the type of stream elements. 573 * @param value the single element of the new stream, may be {@code null}. 574 * @return the new FailableStream on {@code value} or an empty stream. 575 * @since 3.15.0 576 */ 577 public static <T> FailableStream<T> failableStream(final T value) { 578 return failableStream(streamOf(value)); 579 } 580 581 /** 582 * Shorthand for {@code Streams.failableStream(Streams.of(arrayValues))}. 583 * 584 * @param <T> the type of stream elements. 585 * @param values the elements of the new stream, may be {@code null}. 586 * @return the new FailableStream on {@code values} or an empty stream. 587 * @since 3.14.0 588 */ 589 @SafeVarargs // Creating a stream from an array is safe 590 public static <T> FailableStream<T> failableStream(final T... values) { 591 return failableStream(of(values)); 592 } 593 594 /** 595 * Streams only instances of the give Class in a collection. 596 * <p> 597 * This method shorthand for: 598 * </p> 599 * <pre> 600 * {@code (Stream<E>) Streams.toStream(collection).filter(collection, SomeClass.class::isInstance);} 601 * </pre> 602 * 603 * @param <E> the type of elements in the collection we want to stream. 604 * @param clazz the type of elements in the collection we want to stream. 605 * @param collection the collection to stream or null. 606 * @return A non-null stream that only provides instances we want. 607 * @since 3.13.0 608 */ 609 public static <E> Stream<E> instancesOf(final Class<? super E> clazz, final Collection<? super E> collection) { 610 return instancesOf(clazz, of(collection)); 611 } 612 613 @SuppressWarnings("unchecked") // After the isInstance check, we still need to type-cast. 614 private static <E> Stream<E> instancesOf(final Class<? super E> clazz, final Stream<?> stream) { 615 return (Stream<E>) of(stream).filter(clazz::isInstance); 616 } 617 618 /** 619 * Streams the non-null elements of a collection. 620 * 621 * @param <E> the type of elements in the collection. 622 * @param collection the collection to stream or null. 623 * @return A non-null stream that filters out null elements. 624 * @since 3.13.0 625 */ 626 public static <E> Stream<E> nonNull(final Collection<E> collection) { 627 return of(collection).filter(Objects::nonNull); 628 } 629 630 /** 631 * Streams the non-null element. 632 * 633 * @param <E> the type of elements in the collection. 634 * @param array the element to stream or null. 635 * @return A non-null stream that filters out a null element. 636 * @since 3.15.0 637 */ 638 public static <E> Stream<E> nonNull(final E array) { 639 return nonNull(streamOf(array)); 640 } 641 642 /** 643 * Streams the non-null elements of an array. 644 * 645 * @param <E> the type of elements in the collection. 646 * @param array the array to stream or null. 647 * @return A non-null stream that filters out null elements. 648 * @since 3.13.0 649 */ 650 @SafeVarargs 651 public static <E> Stream<E> nonNull(final E... array) { 652 return nonNull(of(array)); 653 } 654 655 /** 656 * Streams the non-null elements of a stream. 657 * 658 * @param <E> the type of elements in the collection. 659 * @param stream the stream to stream or null. 660 * @return A non-null stream that filters out null elements. 661 * @since 3.13.0 662 */ 663 public static <E> Stream<E> nonNull(final Stream<E> stream) { 664 return of(stream).filter(Objects::nonNull); 665 } 666 667 /** 668 * Delegates to {@link Collection#stream()} or returns {@link Stream#empty()} if the collection is null. 669 * 670 * @param <E> the type of elements in the collection. 671 * @param collection the collection to stream or null. 672 * @return {@link Collection#stream()} or {@link Stream#empty()} if the collection is null. 673 * @since 3.13.0 674 */ 675 public static <E> Stream<E> of(final Collection<E> collection) { 676 return collection == null ? Stream.empty() : collection.stream(); 677 } 678 679 /** 680 * Streams the elements of the given enumeration in order. 681 * 682 * @param <E> The enumeration element type. 683 * @param enumeration The enumeration to stream. 684 * @return a new stream. 685 * @since 3.13.0 686 */ 687 public static <E> Stream<E> of(final Enumeration<E> enumeration) { 688 return StreamSupport.stream(new EnumerationSpliterator<>(Long.MAX_VALUE, Spliterator.ORDERED, enumeration), false); 689 } 690 691 /** 692 * Creates a stream on the given Iterable. 693 * 694 * @param <E> the type of elements in the Iterable. 695 * @param iterable the Iterable to stream or null. 696 * @return a new Stream or {@link Stream#empty()} if the Iterable is null. 697 * @since 3.13.0 698 */ 699 public static <E> Stream<E> of(final Iterable<E> iterable) { 700 return iterable == null ? Stream.empty() : StreamSupport.stream(iterable.spliterator(), false); 701 } 702 703 /** 704 * Creates a stream on the given Iterator. 705 * 706 * @param <E> the type of elements in the Iterator. 707 * @param iterator the Iterator to stream or null. 708 * @return a new Stream or {@link Stream#empty()} if the Iterator is null. 709 * @since 3.13.0 710 */ 711 public static <E> Stream<E> of(final Iterator<E> iterator) { 712 return iterator == null ? Stream.empty() : StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false); 713 } 714 715 /** 716 * Returns the stream or {@link Stream#empty()} if the stream is null. 717 * 718 * @param <E> the type of elements in the collection. 719 * @param stream the stream to stream or null. 720 * @return the stream or {@link Stream#empty()} if the stream is null. 721 * @since 3.13.0 722 */ 723 private static <E> Stream<E> of(final Stream<E> stream) { 724 return stream == null ? Stream.empty() : stream; 725 } 726 727 /** 728 * Null-safe version of {@link Stream#of(Object[])}. 729 * 730 * @param <T> the type of stream elements. 731 * @param values the elements of the new stream, may be {@code null}. 732 * @return the new stream on {@code values} or {@link Stream#empty()}. 733 * @since 3.13.0 734 */ 735 @SafeVarargs // Creating a stream from an array is safe 736 public static <T> Stream<T> of(final T... values) { 737 return values == null ? Stream.empty() : Stream.of(values); 738 } 739 740 /** 741 * Converts the given {@link Collection} into a {@link FailableStream}. This is basically a simplified, reduced version 742 * of the {@link Stream} class, with the same underlying element stream, except that failable objects, like 743 * {@link FailablePredicate}, {@link FailableFunction}, or {@link FailableConsumer} may be applied, instead of 744 * {@link Predicate}, {@link Function}, or {@link Consumer}. The idea is to rewrite a code snippet like this: 745 * 746 * <pre> 747 * {@code 748 * final List<O> list; 749 * final Method m; 750 * final Function<O, String> mapper = (o) -> { 751 * try { 752 * return (String) m.invoke(o); 753 * } catch (Throwable t) { 754 * throw Failable.rethrow(t); 755 * } 756 * }; 757 * final List<String> strList = list.stream().map(mapper).collect(Collectors.toList()); 758 * } 759 * </pre> 760 * 761 * as follows: 762 * 763 * <pre> 764 * {@code 765 * final List<O> list; 766 * final Method m; 767 * final List<String> strList = Failable.stream(list.stream()).map((o) -> (String) m.invoke(o)).collect(Collectors.toList()); 768 * } 769 * </pre> 770 * 771 * While the second version may not be <em>quite</em> as efficient (because it depends on the creation of additional, 772 * intermediate objects, of type FailableStream), it is much more concise, and readable, and meets the spirit of Lambdas 773 * better than the first version. 774 * 775 * @param <E> The streams element type. 776 * @param collection The stream, which is being converted. 777 * @return The {@link FailableStream}, which has been created by converting the stream. 778 * @deprecated Use {@link #failableStream(Collection)}. 779 */ 780 @Deprecated 781 public static <E> FailableStream<E> stream(final Collection<E> collection) { 782 return failableStream(collection); 783 } 784 785 /** 786 * Converts the given {@link Stream stream} into a {@link FailableStream}. This is basically a simplified, reduced 787 * version of the {@link Stream} class, with the same underlying element stream, except that failable objects, like 788 * {@link FailablePredicate}, {@link FailableFunction}, or {@link FailableConsumer} may be applied, instead of 789 * {@link Predicate}, {@link Function}, or {@link Consumer}. The idea is to rewrite a code snippet like this: 790 * 791 * <pre> 792 * {@code 793 * final List<O> list; 794 * final Method m; 795 * final Function<O, String> mapper = (o) -> { 796 * try { 797 * return (String) m.invoke(o); 798 * } catch (Throwable t) { 799 * throw Failable.rethrow(t); 800 * } 801 * }; 802 * final List<String> strList = list.stream().map(mapper).collect(Collectors.toList()); 803 * } 804 * </pre> 805 * 806 * as follows: 807 * 808 * <pre> 809 * {@code 810 * final List<O> list; 811 * final Method m; 812 * final List<String> strList = Failable.stream(list.stream()).map((o) -> (String) m.invoke(o)).collect(Collectors.toList()); 813 * } 814 * </pre> 815 * 816 * While the second version may not be <em>quite</em> as efficient (because it depends on the creation of additional, 817 * intermediate objects, of type FailableStream), it is much more concise, and readable, and meets the spirit of Lambdas 818 * better than the first version. 819 * 820 * @param <T> The streams element type. 821 * @param stream The stream, which is being converted. 822 * @return The {@link FailableStream}, which has been created by converting the stream. 823 * @deprecated Use {@link #failableStream(Stream)}. 824 */ 825 @Deprecated 826 public static <T> FailableStream<T> stream(final Stream<T> stream) { 827 return failableStream(stream); 828 } 829 830 private static <T> Stream<T> streamOf(final T value) { 831 return value == null ? Stream.empty() : Stream.of(value); 832 } 833 834 /** 835 * Returns a {@link Collector} that accumulates the input elements into a new array. 836 * 837 * @param elementType Type of an element in the array. 838 * @param <T> the type of the input elements 839 * @return a {@link Collector} which collects all the input elements into an array, in encounter order 840 */ 841 public static <T> Collector<T, ?, T[]> toArray(final Class<T> elementType) { 842 return new ArrayCollector<>(elementType); 843 } 844 845 /** 846 * Constructs a new instance. 847 * 848 * @deprecated Will be private in 4.0.0. 849 */ 850 @Deprecated 851 public Streams() { 852 // empty 853 } 854}