View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.lang3.stream;
18  
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.Enumeration;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.Objects;
26  import java.util.Set;
27  import java.util.Spliterator;
28  import java.util.Spliterators;
29  import java.util.Spliterators.AbstractSpliterator;
30  import java.util.function.BiConsumer;
31  import java.util.function.BinaryOperator;
32  import java.util.function.Consumer;
33  import java.util.function.Function;
34  import java.util.function.Predicate;
35  import java.util.function.Supplier;
36  import java.util.stream.Collector;
37  import java.util.stream.Collectors;
38  import java.util.stream.Stream;
39  import java.util.stream.StreamSupport;
40  
41  import org.apache.commons.lang3.ArrayUtils;
42  import org.apache.commons.lang3.function.Failable;
43  import org.apache.commons.lang3.function.FailableConsumer;
44  import org.apache.commons.lang3.function.FailableFunction;
45  import org.apache.commons.lang3.function.FailablePredicate;
46  
47  /**
48   * Provides utility functions, and classes for working with the {@code java.util.stream} package, or more generally,
49   * with Java 8 lambdas. More specifically, it attempts to address the fact that lambdas are supposed not to throw
50   * Exceptions, at least not checked Exceptions, AKA instances of {@link Exception}. This enforces the use of constructs
51   * like:
52   *
53   * <pre>
54   * {@code
55   * Consumer<java.lang.reflect.Method> consumer = m -> {
56   *     try {
57   *         m.invoke(o, args);
58   *     } catch (Throwable t) {
59   *         throw Failable.rethrow(t);
60   *     }
61   * };
62   * stream.forEach(consumer);
63   * }
64   * </pre>
65   * <p>
66   * Using a {@link FailableStream}, this can be rewritten as follows:
67   * </p>
68   *
69   * <pre>
70   * {@code
71   * Streams.failable(stream).forEach((m) -> m.invoke(o, args));
72   * }
73   * </pre>
74   *
75   * Obviously, the second version is much more concise and the spirit of Lambda expressions is met better than in the
76   * first version.
77   *
78   * @see Stream
79   * @see Failable
80   * @since 3.11
81   */
82  public class Streams {
83  
84      /**
85       * A Collector type for arrays.
86       *
87       * @param <E> The array type.
88       */
89      public static class ArrayCollector<E> implements Collector<E, List<E>, E[]> {
90          private static final Set<Characteristics> characteristics = Collections.emptySet();
91          private final Class<E> elementType;
92  
93          /**
94           * Constructs a new instance for the given element type.
95           *
96           * @param elementType The element type.
97           */
98          public ArrayCollector(final Class<E> elementType) {
99              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 }