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