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}