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 * https://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 {@link java.util.stream} package, or more generally, with Java 8 lambdas. More specifically, it
49 * attempts to address the fact that lambdas are supposed not to throw Exceptions, at least not checked Exceptions, AKA instances of {@link Exception}. This
50 * enforces the use of constructs like:
51 *
52 * <pre>{@code
53 * Consumer<java.lang.reflect.Method> consumer = m -> {
54 * try {
55 * m.invoke(o, args);
56 * } catch (Throwable t) {
57 * throw Failable.rethrow(t);
58 * }
59 * };
60 * stream.forEach(consumer);
61 * }</pre>
62 * <p>
63 * Using a {@link FailableStream}, this can be rewritten as follows:
64 * </p>
65 *
66 * <pre>{@code
67 * Streams.failable(stream).forEach(m -> m.invoke(o, args));
68 * }</pre>
69 * <p>
70 * Obviously, the second version is much more concise and the spirit of Lambda expressions is met better than in the first version.
71 * </p>
72 *
73 * @see Stream
74 * @see Failable
75 * @since 3.11
76 */
77 public class Streams {
78
79 /**
80 * A Collector type for arrays.
81 *
82 * @param <E> The array type.
83 */
84 public static class ArrayCollector<E> implements Collector<E, List<E>, E[]> {
85 private static final Set<Characteristics> characteristics = Collections.emptySet();
86 private final Class<E> elementType;
87
88 /**
89 * Constructs a new instance for the given element type.
90 *
91 * @param elementType The element type.
92 */
93 public ArrayCollector(final Class<E> elementType) {
94 this.elementType = Objects.requireNonNull(elementType, "elementType");
95 }
96
97 @Override
98 public BiConsumer<List<E>, E> accumulator() {
99 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 sequential 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 sequential 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 <T> the type of the input elements
838 * @param elementType Type of an element in the array.
839 * @return a {@link Collector} which collects all the input elements into an array, in encounter order
840 */
841 public static <T> Collector<T, List<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 }