1616import java .util .*;
1717import java .util .concurrent .*;
1818import java .util .concurrent .atomic .AtomicLong ;
19- import java .util .stream .Stream ;
19+ import java .util .stream .* ;
2020
2121import io .reactivex .rxjava4 .annotations .*;
2222import io .reactivex .rxjava4 .core .config .*;
@@ -539,10 +539,56 @@ static Streamable<Long> timer(long delay, TimeUnit unit, ExecutorService executo
539539 return RxJavaPlugins .onAssembly (new StreamableTimer (delay , unit , null , executor ));
540540 }
541541
542+ /**
543+ * Takes the next element from each source {@code Streamable} and emits them a a single
544+ * row of {@link List}.
545+ * <p>
546+ * If any of the sources is shorter than the rest or any of them fails, the
547+ * sequence is completed early normally or with an exception, respectively.
548+ * @param <T> the common element type of the sequences
549+ * @param sources the iterable sequence of the source {@code Streamable}s
550+ * @return the new {@code Streamable} instance
551+ * @throws NullPointerException if {@code sources} is {@&ode null}
552+ */
553+ static <T > Streamable <List <T >> zip (Iterable <? extends Streamable <? extends T >> sources ) {
554+ Objects .requireNonNull (sources , "sources is null" );
555+ return RxJavaPlugins .onAssembly (new StreamableZip <>(sources ));
556+ }
557+
542558 // oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
543559 // Operators
544560 // oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
545561
562+ /**
563+ * Collects all upstream values via the use of a {@link Collector} configuration
564+ * and emits its resulting value as a single item of the returned {@code Streamable}.
565+ * <p>
566+ * See {@link Collectors} for the most typical collector standard implementations.
567+ * @param <A> the accumulator type of the collector
568+ * @param <R> the result type of the collector and the returned {@code Streamamble}
569+ * @param collector the Java collector instance to use
570+ * @return the new {@code Streamable} instance
571+ * @throws NullPointerException if {@code collector} is {@code null}
572+ */
573+ default <A , R > Streamable <R > collect (Collector <T , A , R > collector ) {
574+ Objects .requireNonNull (collector , "collector is null" );
575+ return RxJavaPlugins .onAssembly (new StreamableCollector <>(this , collector ));
576+ }
577+
578+ /**
579+ * Delays the delivery of each upstream item by the given time amount.
580+ * @param time the delay time
581+ * @param unit the time unit
582+ * @param scheduler the scheduler where the timed wait is happening
583+ * @return the new {@code Streamable} instance
584+ * @throws NullPointerException if {@code unit} or {@code scheduler} is {@code null}
585+ */
586+ default Streamable <T > delay (long time , TimeUnit unit , Scheduler scheduler ) {
587+ Objects .requireNonNull (unit , "unit is null" );
588+ Objects .requireNonNull (scheduler , "scheduler is null" );
589+ return RxJavaPlugins .onAssembly (new StreamableDelay <>(this , time , unit , scheduler ));
590+ }
591+
546592 /**
547593 * Calls the given consumer whenever an upstream item becomes available.
548594 * @param consumer the callback to invoke with the next item from upstream
@@ -667,6 +713,19 @@ default Streamable<T> intercept(StreamableInterceptConfig<T> config) {
667713 return RxJavaPlugins .onAssembly (new StreamableMapOptional <>(this , mapper ));
668714 }
669715
716+ /**
717+ * When the upstream fails, the sequence is resumed by the {@code Streamable} that is returned for the
718+ * failure {@link Throwable}.
719+ * @param fallbackMapper the function that receives the upstream error and should return a
720+ * {@code Streamable} to resume the sequence with
721+ * @return the new {@code Streamable} instance
722+ * @throws NullPointerException if {@code fallbackMapper} is {@code null}
723+ */
724+ default Streamable <T > onErrorResumeNext (Function <? super Throwable , ? extends Streamable <? extends T >> fallbackMapper ) {
725+ Objects .requireNonNull (fallbackMapper , "fallbackMapper is null" );
726+ return RxJavaPlugins .onAssembly (new StreamableOnErrorResumeNext <>(this , fallbackMapper ));
727+ }
728+
670729 /**
671730 * Takes at most the given number of items from the upstream and relays it to the downstream,
672731 * then cancels the rest of the sequence.
@@ -689,6 +748,21 @@ default Streamable<T> take(long n) {
689748 });
690749 }
691750
751+ /**
752+ * Relays items from this {@code Streamable} until the other {@code Streamable} signals
753+ * an item or completes.
754+ * @param <U> the element type of the other {@code Streamable}
755+ * @param other the {@code Streamable} expected to signal when to stop taking items from this {@code Streamable}
756+ * @return the new {@code Streamable} instance
757+ * @throws NullPointerException if {@code other} is {@code null}
758+ */
759+ @ CheckReturnValue
760+ @ NonNull
761+ default <U > Streamable <T > takeUntil (@ NonNull Streamable <U > other ) {
762+ Objects .requireNonNull (other , "other is null" );
763+ return RxJavaPlugins .onAssembly (new StreamableTakeUntil <>(this , other ));
764+ }
765+
692766 /**
693767 * Relays items from this {@code Streamable} while the predicate returns {@code true}
694768 * @param predicate the predicate to test if the sequence should keep going
@@ -703,18 +777,21 @@ default Streamable<T> takeWhile(@NonNull Predicate<? super T> predicate) {
703777 }
704778
705779 /**
706- * Relays items from this {@code Streamable} until the other {@code Streamable} signals
707- * an item or completes.
708- * @param <U> the element type of the other {@code Streamable}
709- * @param other the {@code Streamable} expected to signal when to stop taking items from this {@code Streamable}
780+ * Applies a timeout to each upstream item and switches to the fallback {@code Streamable}
781+ * if the upstream doesn't produce an item within the given timeout period.
782+ * @param timeout the time to wait for each upstream item
783+ * @param unit the time unit
784+ * @param scheduler the scheduler where to wait for the next upstream item
785+ * @param fallback the {@code Streamable} to switch to if the upstream doesn't produce an item
786+ * within the time limit
710787 * @return the new {@code Streamable} instance
711- * @throws NullPointerException if {@code other } is {@code null}
788+ * @throws NullPointerException if {@code unit} or {@code scheduler} or {@code fallback } is {@code null}
712789 */
713- @ CheckReturnValue
714- @ NonNull
715- default < U > Streamable < T > takeUntil ( @ NonNull Streamable < U > other ) {
716- Objects .requireNonNull (other , "other is null" );
717- return RxJavaPlugins .onAssembly (new StreamableTakeUntil <>(this , other ));
790+ default Streamable < T > timeout ( long timeout , TimeUnit unit , Scheduler scheduler , Streamable < T > fallback ) {
791+ Objects . requireNonNull ( unit , "unit is null" );
792+ Objects . requireNonNull ( scheduler , "scheduler is null" );
793+ Objects .requireNonNull (fallback , "fallback is null" );
794+ return RxJavaPlugins .onAssembly (new StreamableTimeout <>(this , timeout , unit , scheduler , fallback ));
718795 }
719796
720797 /**
@@ -891,8 +968,8 @@ default CompletionStageDisposable<Void> forEach(
891968 default void subscribe (@ NonNull Flow .Subscriber <? super T > subscriber , @ NonNull ExecutorService executor ) {
892969 final Streamable <T > me = this ;
893970 Flowable .<T >virtualCreate (emitter -> {
894- me .forEach (emitter ::emit , emitter .canceller ().derive (), executor )
895- .await ();
971+ var cf = me .forEach (emitter ::emit , emitter .canceller ().derive (), executor );
972+ cf .await ();
896973 }, executor )
897974 .subscribe (subscriber );
898975 }
0 commit comments