io.reactivex.rxjava3.core.Single Maven / Gradle / Ivy
Show all versions of rxjava Show documentation
/*
* Copyright (c) 2016-present, RxJava Contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
* the License for the specific language governing permissions and limitations under the License.
*/
package io.reactivex.rxjava3.core;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
import org.reactivestreams.*;
import io.reactivex.rxjava3.annotations.*;
import io.reactivex.rxjava3.disposables.*;
import io.reactivex.rxjava3.exceptions.*;
import io.reactivex.rxjava3.functions.*;
import io.reactivex.rxjava3.internal.functions.*;
import io.reactivex.rxjava3.internal.fuseable.*;
import io.reactivex.rxjava3.internal.jdk8.*;
import io.reactivex.rxjava3.internal.observers.*;
import io.reactivex.rxjava3.internal.operators.completable.*;
import io.reactivex.rxjava3.internal.operators.flowable.*;
import io.reactivex.rxjava3.internal.operators.maybe.*;
import io.reactivex.rxjava3.internal.operators.mixed.*;
import io.reactivex.rxjava3.internal.operators.observable.ObservableSingleSingle;
import io.reactivex.rxjava3.internal.operators.single.*;
import io.reactivex.rxjava3.internal.util.ErrorMode;
import io.reactivex.rxjava3.observers.TestObserver;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
import io.reactivex.rxjava3.schedulers.*;
/**
* The {@code Single} class implements the Reactive Pattern for a single value response.
*
* {@code Single} behaves similarly to {@link Observable} except that it can only emit either a single successful
* value or an error (there is no {@code onComplete} notification as there is for an {@code Observable}).
*
* The {@code Single} class implements the {@link SingleSource} base interface and the default consumer
* type it interacts with is the {@link SingleObserver} via the {@link #subscribe(SingleObserver)} method.
*
* The {@code Single} operates with the following sequential protocol:
*
* onSubscribe (onSuccess | onError)?
*
*
* Note that {@code onSuccess} and {@code onError} are mutually exclusive events; unlike {@code Observable},
* {@code onSuccess} is never followed by {@code onError}.
*
* Like {@code Observable}, a running {@code Single} can be stopped through the {@link Disposable} instance
* provided to consumers through {@link SingleObserver#onSubscribe}.
*
* Like an {@code Observable}, a {@code Single} is lazy, can be either "hot" or "cold", synchronous or
* asynchronous. {@code Single} instances returned by the methods of this class are cold
* and there is a standard hot implementation in the form of a subject:
* {@link io.reactivex.rxjava3.subjects.SingleSubject SingleSubject}.
*
* The documentation for this class makes use of marble diagrams. The following legend explains these diagrams:
*
*
*
* See {@link Flowable} or {@code Observable} for the
* implementation of the Reactive Pattern for a stream or vector of values.
*
* For more information see the ReactiveX
* documentation.
*
* Example:
*
* Disposable d = Single.just("Hello World")
* .delay(10, TimeUnit.SECONDS, Schedulers.io())
* .subscribeWith(new DisposableSingleObserver<String>() {
* @Override
* public void onStart() {
* System.out.println("Started");
* }
*
* @Override
* public void onSuccess(String value) {
* System.out.println("Success: " + value);
* }
*
* @Override
* public void onError(Throwable error) {
* error.printStackTrace();
* }
* });
*
* Thread.sleep(5000);
*
* d.dispose();
*
*
* Note that by design, subscriptions via {@link #subscribe(SingleObserver)} can't be disposed
* from the outside (hence the
* {@code void} return of the {@link #subscribe(SingleObserver)} method) and it is the
* responsibility of the implementor of the {@code SingleObserver} to allow this to happen.
* RxJava supports such usage with the standard
* {@link io.reactivex.rxjava3.observers.DisposableSingleObserver DisposableSingleObserver} instance.
* For convenience, the {@link #subscribeWith(SingleObserver)} method is provided as well to
* allow working with a {@code SingleObserver} (or subclass) instance to be applied with in
* a fluent manner (such as in the example above).
* @param
* the type of the item emitted by the {@code Single}
* @since 2.0
* @see io.reactivex.rxjava3.observers.DisposableSingleObserver
*/
public abstract class Single<@NonNull T> implements SingleSource {
/**
* Runs multiple {@link SingleSource}s and signals the events of the first one that signals (disposing
* the rest).
*
*
*
* - Scheduler:
* - {@code amb} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the {@link Iterable} sequence of sources. A subscription to each source will
* occur in the same order as in this {@code Iterable}.
* @return the new {@code Single} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single amb(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new SingleAmb<>(null, sources));
}
/**
* Runs multiple {@link SingleSource}s and signals the events of the first one that signals (disposing
* the rest).
*
*
*
* - Scheduler:
* - {@code ambArray} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the array of sources. A subscription to each source will
* occur in the same order as in this array.
* @return the new {@code Single} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
@NonNull
public static <@NonNull T> Single ambArray(@NonNull SingleSource extends T>... sources) {
Objects.requireNonNull(sources, "sources is null");
if (sources.length == 0) {
return error(SingleInternalHelper.emptyThrower());
}
if (sources.length == 1) {
@SuppressWarnings("unchecked")
SingleSource source = (SingleSource)sources[0];
return wrap(source);
}
return RxJavaPlugins.onAssembly(new SingleAmb<>(sources, null));
}
/**
* Concatenate the single values, in a non-overlapping fashion, of the {@link SingleSource}s provided by
* an {@link Iterable} sequence.
*
*
*
* - Backpressure:
* - The returned {@link Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the {@code Iterable} sequence of {@code SingleSource} instances
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
public static <@NonNull T> Flowable concat(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromIterable(sources).concatMapSingleDelayError(Functions.identity(), false);
}
/**
* Concatenate the single values, in a non-overlapping fashion, of the {@link SingleSource}s provided by
* an {@link ObservableSource} sequence.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the {@code ObservableSource} of {@code SingleSource} instances
* @return the new {@link Observable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Observable concat(@NonNull ObservableSource extends SingleSource extends T>> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new ObservableConcatMapSingle<>(sources, Functions.identity(), ErrorMode.IMMEDIATE, 2));
}
/**
* Concatenate the single values, in a non-overlapping fashion, of the {@link SingleSource}s provided by
* a {@link Publisher} sequence.
*
*
*
* - Backpressure:
* - The returned {@link Flowable} honors the backpressure of the downstream consumer
* and the sources {@code Publisher} is expected to honor it as well.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the {@code Publisher} of {@code SingleSource} instances
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concat(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
return concat(sources, 2);
}
/**
* Concatenate the single values, in a non-overlapping fashion, of the {@link SingleSource}s provided by
* a {@link Publisher} sequence and prefetched by the specified amount.
*
*
*
* - Backpressure:
* - The returned {@link Flowable} honors the backpressure of the downstream consumer
* and the sources {@code Publisher} is expected to honor it as well.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the {@code Publisher} of {@code SingleSource} instances
* @param prefetch the number of {@code SingleSource}s to prefetch from the {@code Publisher}
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code prefetch} is non-positive
* @since 2.0
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concat(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources, int prefetch) {
Objects.requireNonNull(sources, "sources is null");
ObjectHelper.verifyPositive(prefetch, "prefetch");
return RxJavaPlugins.onAssembly(new FlowableConcatMapSinglePublisher<>(sources, Functions.identity(), ErrorMode.IMMEDIATE, prefetch));
}
/**
* Returns a {@link Flowable} that emits the items emitted by two {@link SingleSource}s, one after the other.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param source1
* a {@code SingleSource} to be concatenated
* @param source2
* a {@code SingleSource} to be concatenated
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code source1} or {@code source2} is {@code null}
* @see ReactiveX operators documentation: Concat
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concat(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
return Flowable.fromArray(source1, source2).concatMapSingleDelayError(Functions.identity(), false);
}
/**
* Returns a {@link Flowable} that emits the items emitted by three {@link SingleSource}s, one after the other.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param source1
* a {@code SingleSource} to be concatenated
* @param source2
* a {@code SingleSource} to be concatenated
* @param source3
* a {@code SingleSource} to be concatenated
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code source1}, {@code source2} or {@code source3} is {@code null}
* @see ReactiveX operators documentation: Concat
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concat(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2,
@NonNull SingleSource extends T> source3
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
return Flowable.fromArray(source1, source2, source3).concatMapSingleDelayError(Functions.identity(), false);
}
/**
* Returns a {@link Flowable} that emits the items emitted by four {@link SingleSource}s, one after the other.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common value type
* @param source1
* a {@code SingleSource} to be concatenated
* @param source2
* a {@code SingleSource} to be concatenated
* @param source3
* a {@code SingleSource} to be concatenated
* @param source4
* a {@code SingleSource} to be concatenated
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3} or {@code source4} is {@code null}
* @see ReactiveX operators documentation: Concat
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concat(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2,
@NonNull SingleSource extends T> source3, @NonNull SingleSource extends T> source4
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
return Flowable.fromArray(source1, source2, source3, source4).concatMapSingleDelayError(Functions.identity(), false);
}
/**
* Concatenate the single values, in a non-overlapping fashion, of the {@link SingleSource}s provided in
* an array.
*
*
*
* - Backpressure:
* - The returned {@link Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code concatArray} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the array of {@code SingleSource} instances
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static <@NonNull T> Flowable concatArray(@NonNull SingleSource extends T>... sources) {
return Flowable.fromArray(sources).concatMapSingleDelayError(Functions.identity(), false);
}
/**
* Concatenate the single values, in a non-overlapping fashion, of the {@link SingleSource}s provided in
* an array.
*
*
*
* - Backpressure:
* - The returned {@link Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code concatArrayDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources the array of {@code SingleSource} instances
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static <@NonNull T> Flowable concatArrayDelayError(@NonNull SingleSource extends T>... sources) {
return Flowable.fromArray(sources).concatMapSingleDelayError(Functions.identity(), true);
}
/**
* Concatenates a sequence of {@link SingleSource} eagerly into a single stream of values.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* source {@code SingleSource}s. The operator buffers the value emitted by these {@code SingleSource}s and then drains them
* in order, each one after the previous one succeeds.
*
* - Backpressure:
* - The operator honors backpressure from downstream.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources a sequence of {@code SingleSource}s that need to be eagerly concatenated
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static <@NonNull T> Flowable concatArrayEager(@NonNull SingleSource extends T>... sources) {
return Flowable.fromArray(sources).concatMapEager(SingleInternalHelper.toFlowable());
}
/**
* Concatenates a sequence of {@link SingleSource} eagerly into a single stream of values.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* source {@code SingleSource}s. The operator buffers the value emitted by these {@code SingleSource}s and then drains them
* in order, each one after the previous one succeeds.
*
* - Backpressure:
* - The operator honors backpressure from downstream.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources a sequence of {@code SingleSource}s that need to be eagerly concatenated
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static <@NonNull T> Flowable concatArrayEagerDelayError(@NonNull SingleSource extends T>... sources) {
return Flowable.fromArray(sources).concatMapEagerDelayError(SingleInternalHelper.toFlowable(), true);
}
/**
* Concatenates the {@link Iterable} sequence of {@link SingleSource}s into a single sequence by subscribing to each {@code SingleSource},
* one after the other, one at a time and delays any errors till the all inner {@code SingleSource}s terminate
* as a {@link Flowable} sequence.
*
*
*
* - Backpressure:
* - The operator honors backpressure from downstream.
* - Scheduler:
* - {@code concatDelayError} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common element base type
* @param sources the {@code Iterable} sequence of {@code SingleSource}s
* @return the new {@code Flowable} with the concatenating behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatDelayError(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromIterable(sources).concatMapSingleDelayError(Functions.identity());
}
/**
* Concatenates the {@link Publisher} sequence of {@link SingleSource}s into a single sequence by subscribing to each inner {@code SingleSource},
* one after the other, one at a time and delays any errors till the all inner and the outer {@code Publisher} terminate
* as a {@link Flowable} sequence.
*
*
*
* - Backpressure:
* - {@code concatDelayError} fully supports backpressure.
* - Scheduler:
* - {@code concatDelayError} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common element base type
* @param sources the {@code Publisher} sequence of {@code SingleSource}s
* @return the new {@code Flowable} with the concatenating behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <@NonNull T> Flowable concatDelayError(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromPublisher(sources).concatMapSingleDelayError(Functions.identity());
}
/**
* Concatenates the {@link Publisher} sequence of {@link SingleSource}s into a single sequence by subscribing to each inner {@code SingleSource},
* one after the other, one at a time and delays any errors till the all inner and the outer {@code Publisher} terminate
* as a {@link Flowable} sequence.
*
*
*
* - Backpressure:
* - {@code concatDelayError} fully supports backpressure.
* - Scheduler:
* - {@code concatDelayError} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common element base type
* @param sources the {@code Publisher} sequence of {@code SingleSource}s
* @param prefetch The number of upstream items to prefetch so that fresh items are
* ready to be mapped when a previous {@code SingleSource} terminates.
* The operator replenishes after half of the prefetch amount has been consumed
* and turned into {@code SingleSource}s.
* @return the new {@code Flowable} with the concatenating behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code prefetch} is non-positive
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <@NonNull T> Flowable concatDelayError(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources, int prefetch) {
return Flowable.fromPublisher(sources).concatMapSingleDelayError(Functions.identity(), true, prefetch);
}
/**
* Concatenates an {@link Iterable} sequence of {@link SingleSource}s eagerly into a single stream of values.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* source {@code SingleSource}s. The operator buffers the values emitted by these {@code SingleSource}s and then drains them
* in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources an {@code Iterable} sequence of {@code SingleSource} that need to be eagerly concatenated
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEager(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromIterable(sources).concatMapEagerDelayError(SingleInternalHelper.toFlowable(), false);
}
/**
* Concatenates an {@link Iterable} sequence of {@link SingleSource}s eagerly into a single stream of values and
* runs a limited number of the inner sources at once.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* source {@code SingleSource}s. The operator buffers the values emitted by these {@code SingleSource}s and then drains them
* in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources an {@code Iterable} sequence of {@code SingleSource} that need to be eagerly concatenated
* @param maxConcurrency the maximum number of concurrently running inner {@code SingleSource}s; {@link Integer#MAX_VALUE}
* is interpreted as all inner {@code SingleSource}s can be active at the same time
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code maxConcurrency} is non-positive
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEager(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources, int maxConcurrency) {
return Flowable.fromIterable(sources).concatMapEagerDelayError(SingleInternalHelper.toFlowable(), false, maxConcurrency, 1);
}
/**
* Concatenates a {@link Publisher} sequence of {@link SingleSource}s eagerly into a single stream of values.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* emitted source {@code SingleSource}s as they are observed. The operator buffers the values emitted by these
* {@code SingleSource}s and then drains them in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream and the outer {@code Publisher} is
* expected to support backpressure. Violating this assumption, the operator will
* signal {@link io.reactivex.rxjava3.exceptions.MissingBackpressureException}.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources a sequence of {@code SingleSource}s that need to be eagerly concatenated
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEager(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromPublisher(sources).concatMapEager(SingleInternalHelper.toFlowable());
}
/**
* Concatenates a {@link Publisher} sequence of {@link SingleSource}s eagerly into a single stream of values and
* runs a limited number of those inner {@code SingleSource}s at once.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* emitted source {@code SingleSource}s as they are observed. The operator buffers the values emitted by these
* {@code SingleSource}s and then drains them in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream and the outer {@code Publisher} is
* expected to support backpressure. Violating this assumption, the operator will
* signal {@link io.reactivex.rxjava3.exceptions.MissingBackpressureException}.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources a sequence of {@code SingleSource}s that need to be eagerly concatenated
* @param maxConcurrency the maximum number of concurrently running inner {@code SingleSource}s; {@link Integer#MAX_VALUE}
* is interpreted as all inner {@code SingleSource}s can be active at the same time
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code maxConcurrency} is non-positive
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEager(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources, int maxConcurrency) {
return Flowable.fromPublisher(sources).concatMapEager(SingleInternalHelper.toFlowable(), maxConcurrency, 1);
}
/**
* Concatenates an {@link Iterable} sequence of {@link SingleSource}s eagerly into a single stream of values,
* delaying errors until all the inner sources terminate.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* source {@code SingleSource}s. The operator buffers the values emitted by these {@code SingleSource}s and then drains them
* in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources an {@code Iterable} sequence of {@code SingleSource} that need to be eagerly concatenated
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEagerDelayError(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromIterable(sources).concatMapEagerDelayError(SingleInternalHelper.toFlowable(), true);
}
/**
* Concatenates an {@link Iterable} sequence of {@link SingleSource}s eagerly into a single stream of values,
* delaying errors until all the inner sources terminate.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* source {@code SingleSource}s. The operator buffers the values emitted by these {@code SingleSource}s and then drains them
* in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources an {@code Iterable} sequence of {@code SingleSource} that need to be eagerly concatenated
* @param maxConcurrency the maximum number of concurrently running inner {@code SingleSource}s; {@link Integer#MAX_VALUE}
* is interpreted as all inner {@code SingleSource}s can be active at the same time
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code maxConcurrency} is non-positive
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEagerDelayError(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources, int maxConcurrency) {
return Flowable.fromIterable(sources).concatMapEagerDelayError(SingleInternalHelper.toFlowable(), true, maxConcurrency, 1);
}
/**
* Concatenates a {@link Publisher} sequence of {@link SingleSource}s eagerly into a single stream of values,
* delaying errors until all the inner and the outer sequence terminate.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* emitted source {@code SingleSource}s as they are observed. The operator buffers the values emitted by these
* {@code SingleSource}s and then drains them in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream and the outer {@code Publisher} is
* expected to support backpressure. Violating this assumption, the operator will
* signal {@link io.reactivex.rxjava3.exceptions.MissingBackpressureException}.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources a sequence of {@code SingleSource}s that need to be eagerly concatenated
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEagerDelayError(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromPublisher(sources).concatMapEagerDelayError(SingleInternalHelper.toFlowable(), true);
}
/**
* Concatenates a {@link Publisher} sequence of {@link SingleSource}s eagerly into a single stream of values,
* running at most the specified number of those inner {@code SingleSource}s at once and
* delaying errors until all the inner and the outer sequence terminate.
*
*
*
* Eager concatenation means that once a subscriber subscribes, this operator subscribes to all of the
* emitted source {@code SingleSource}s as they are observed. The operator buffers the values emitted by these
* {@code SingleSource}s and then drains them in order, each one after the previous one succeeds.
*
* - Backpressure:
* - Backpressure is honored towards the downstream and the outer {@code Publisher} is
* expected to support backpressure. Violating this assumption, the operator will
* signal {@link io.reactivex.rxjava3.exceptions.MissingBackpressureException}.
* - Scheduler:
* - This method does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param sources a sequence of {@code SingleSource}s that need to be eagerly concatenated
* @param maxConcurrency the number of inner {@code SingleSource}s to run at once
* @return the new {@link Flowable} instance with the specified concatenation behavior
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code maxConcurrency} is non-positive
* @since 3.0.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable concatEagerDelayError(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources, int maxConcurrency) {
return Flowable.fromPublisher(sources).concatMapEagerDelayError(SingleInternalHelper.toFlowable(), true, maxConcurrency, 1);
}
/**
* Provides an API (via a cold {@code Single}) that bridges the reactive world with the callback-style world.
*
*
*
* Example:
*
* Single.<Event>create(emitter -> {
* Callback listener = new Callback() {
* @Override
* public void onEvent(Event e) {
* emitter.onSuccess(e);
* }
*
* @Override
* public void onFailure(Exception e) {
* emitter.onError(e);
* }
* };
*
* AutoCloseable c = api.someMethod(listener);
*
* emitter.setCancellable(c::close);
*
* });
*
*
* Whenever a {@link SingleObserver} subscribes to the returned {@code Single}, the provided
* {@link SingleOnSubscribe} callback is invoked with a fresh instance of a {@link SingleEmitter}
* that will interact only with that specific {@code SingleObserver}. If this {@code SingleObserver}
* disposes the flow (making {@link SingleEmitter#isDisposed} return {@code true}),
* other observers subscribed to the same returned {@code Single} are not affected.
*
* - Scheduler:
* - {@code create} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param source the emitter that is called when a {@code SingleObserver} subscribes to the returned {@code Single}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code source} is {@code null}
* @see SingleOnSubscribe
* @see Cancellable
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single create(@NonNull SingleOnSubscribe source) {
Objects.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new SingleCreate<>(source));
}
/**
* Calls a {@link Supplier} for each individual {@link SingleObserver} to return the actual {@link SingleSource} to
* be subscribed to.
*
*
*
* - Scheduler:
* - {@code defer} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param supplier the {@code Supplier} that is called for each individual {@code SingleObserver} and
* returns a {@code SingleSource} instance to subscribe to
* @throws NullPointerException if {@code supplier} is {@code null}
* @return the new {@code Single} instance
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single defer(@NonNull Supplier extends SingleSource extends T>> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return RxJavaPlugins.onAssembly(new SingleDefer<>(supplier));
}
/**
* Signals a {@link Throwable} returned by the callback function for each individual {@link SingleObserver}.
*
*
*
* - Scheduler:
* - {@code error} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param supplier the {@link Supplier} that is called for each individual {@code SingleObserver} and
* returns a {@code Throwable} instance to be emitted.
* @throws NullPointerException if {@code supplier} is {@code null}
* @return the new {@code Single} instance
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single error(@NonNull Supplier extends Throwable> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return RxJavaPlugins.onAssembly(new SingleError<>(supplier));
}
/**
* Returns a {@code Single} that invokes a subscriber's {@link SingleObserver#onError onError} method when the
* subscriber subscribes to it.
*
*
*
* - Scheduler:
* - {@code error} does not operate by default on a particular {@link Scheduler}.
*
*
* @param throwable
* the particular {@link Throwable} to pass to {@link SingleObserver#onError onError}
* @param
* the type of the item (ostensibly) emitted by the {@code Single}
* @return the new {@code Single} that invokes the subscriber's {@link SingleObserver#onError onError} method when
* the subscriber subscribes to it
* @throws NullPointerException if {@code throwable} is {@code null}
* @see ReactiveX operators documentation: Throw
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single error(@NonNull Throwable throwable) {
Objects.requireNonNull(throwable, "throwable is null");
return error(Functions.justSupplier(throwable));
}
/**
* Returns a {@code Single} that invokes the given {@link Callable} for each incoming {@link SingleObserver}
* and emits its value or exception to them.
*
* Allows you to defer execution of passed function until {@code SingleObserver} subscribes to the {@code Single}.
* It makes passed function "lazy".
* Result of the function invocation will be emitted by the {@link Single}.
*
*
*
* - Scheduler:
* - {@code fromCallable} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the {@code Callable} throws an exception, the respective {@link Throwable} is
* delivered to the downstream via {@link SingleObserver#onError(Throwable)},
* except when the downstream has disposed this {@code Single} source.
* In this latter case, the {@code Throwable} is delivered to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} as an {@link io.reactivex.rxjava3.exceptions.UndeliverableException UndeliverableException}.
*
*
*
* @param callable
* function which execution should be deferred, it will be invoked when {@code SingleObserver} will subscribe to the {@link Single}.
* @param
* the type of the item emitted by the {@code Single}.
* @return the new {@code Single} whose {@code SingleObserver}s' subscriptions trigger an invocation of the given function.
* @throws NullPointerException if {@code callable} is {@code null}
* @see #defer(Supplier)
* @see #fromSupplier(Supplier)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single fromCallable(@NonNull Callable extends T> callable) {
Objects.requireNonNull(callable, "callable is null");
return RxJavaPlugins.onAssembly(new SingleFromCallable<>(callable));
}
/**
* Converts a {@link Future} into a {@code Single} and awaits its outcome in a blocking fashion.
*
*
*
* The operator calls {@link Future#get()}, which is a blocking method, on the subscription thread.
* It is recommended applying {@link #subscribeOn(Scheduler)} to move this blocking wait to a
* background thread, and if the {@link Scheduler} supports it, interrupt the wait when the flow
* is disposed.
*
* A non-{@code null} value is then emitted via {@code onSuccess} or any exception is emitted via
* {@code onError}. If the {@code Future} completes with {@code null}, a {@link NullPointerException}
* is signaled.
*
* - Scheduler:
* - {@code fromFuture} does not operate by default on a particular {@code Scheduler}.
*
*
* @param future
* the source {@code Future}
* @param
* the type of object that the {@code Future} returns, and also the type of item to be emitted by
* the resulting {@code Single}
* @return the new {@code Single} that emits the item from the source {@code Future}
* @throws NullPointerException if {@code future} is {@code null}
* @see ReactiveX operators documentation: From
* @see #fromFuture(Future, long, TimeUnit)
* @see #fromCompletionStage(CompletionStage)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <@NonNull T> Single fromFuture(@NonNull Future extends T> future) {
return toSingle(Flowable.fromFuture(future));
}
/**
* Converts a {@link Future} into a {@code Single} and awaits its outcome, or timeout, in a blocking fashion.
*
*
*
* The operator calls {@link Future#get(long, TimeUnit)}, which is a blocking method, on the subscription thread.
* It is recommended applying {@link #subscribeOn(Scheduler)} to move this blocking wait to a
* background thread, and if the {@link Scheduler} supports it, interrupt the wait when the flow
* is disposed.
*
* A non-{@code null} value is then emitted via {@code onSuccess} or any exception is emitted via
* {@code onError}. If the {@code Future} completes with {@code null}, a {@link NullPointerException}
* is signaled.
*
* - Scheduler:
* - {@code fromFuture} does not operate by default on a particular {@code Scheduler}.
*
*
* @param future
* the source {@code Future}
* @param timeout
* the maximum time to wait before calling {@code get}
* @param unit
* the {@link TimeUnit} of the {@code timeout} argument
* @param
* the type of object that the {@code Future} returns, and also the type of item to be emitted by
* the resulting {@code Single}
* @return the new {@code Single} that emits the item from the source {@code Future}
* @throws NullPointerException if {@code future} or {@code unit} is {@code null}
* @see ReactiveX operators documentation: From
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <@NonNull T> Single fromFuture(@NonNull Future extends T> future, long timeout, @NonNull TimeUnit unit) {
return toSingle(Flowable.fromFuture(future, timeout, unit));
}
/**
* Returns a {@code Single} instance that when subscribed to, subscribes to the {@link MaybeSource} instance and
* emits {@code onSuccess} as a single item, turns an {@code onComplete} into {@link NoSuchElementException} error signal or
* forwards the {@code onError} signal.
*
*
*
* - Scheduler:
* - {@code fromMaybe} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type of the {@code MaybeSource} element
* @param maybe the {@code MaybeSource} instance to subscribe to, not {@code null}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code maybe} is {@code null}
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single fromMaybe(@NonNull MaybeSource maybe) {
Objects.requireNonNull(maybe, "maybe is null");
return RxJavaPlugins.onAssembly(new MaybeToSingle<>(maybe, null));
}
/**
* Returns a {@code Single} instance that when subscribed to, subscribes to the {@link MaybeSource} instance and
* emits {@code onSuccess} as a single item, emits the {@code defaultItem} for an {@code onComplete} signal or
* forwards the {@code onError} signal.
*
*
*
* - Scheduler:
* - {@code fromMaybe} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type of the {@code MaybeSource} element
* @param maybe the {@code MaybeSource} instance to subscribe to, not {@code null}
* @param defaultItem the item to signal if the current {@code MaybeSource} is empty
* @return the new {@code Single} instance
* @throws NullPointerException if {@code maybe} or {@code defaultItem} is {@code null}
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single fromMaybe(@NonNull MaybeSource maybe, @NonNull T defaultItem) {
Objects.requireNonNull(maybe, "maybe is null");
Objects.requireNonNull(defaultItem, "defaultItem is null");
return RxJavaPlugins.onAssembly(new MaybeToSingle<>(maybe, defaultItem));
}
/**
* Wraps a specific {@link Publisher} into a {@code Single} and signals its single element or error.
*
*
*
* If the source {@code Publisher} is empty, a {@link NoSuchElementException} is signaled. If
* the source has more than one element, an {@link IndexOutOfBoundsException} is signaled.
*
* The {@code Publisher} must follow the
* Reactive Streams specification.
* Violating the specification may result in undefined behavior.
*
* If possible, use {@link #create(SingleOnSubscribe)} to create a
* source-like {@code Single} instead.
*
* Note that even though {@code Publisher} appears to be a functional interface, it
* is not recommended to implement it through a lambda as the specification requires
* state management that is not achievable with a stateless lambda.
*
* - Backpressure:
* - The {@code publisher} is consumed in an unbounded fashion but will be cancelled
* if it produced more than one item.
* - Scheduler:
* - {@code fromPublisher} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param publisher the source {@code Publisher} instance, not {@code null}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code publisher} is {@code null}
* @see #create(SingleOnSubscribe)
*/
@BackpressureSupport(BackpressureKind.UNBOUNDED_IN)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single fromPublisher(@NonNull Publisher extends T> publisher) {
Objects.requireNonNull(publisher, "publisher is null");
return RxJavaPlugins.onAssembly(new SingleFromPublisher<>(publisher));
}
/**
* Wraps a specific {@link ObservableSource} into a {@code Single} and signals its single element or error.
*
*
*
* If the {@code ObservableSource} is empty, a {@link NoSuchElementException} is signaled.
* If the source has more than one element, an {@link IndexOutOfBoundsException} is signaled.
*
* - Scheduler:
* - {@code fromObservable} does not operate by default on a particular {@link Scheduler}.
*
*
* @param observable the source sequence to wrap, not {@code null}
* @param
* the type of the item emitted by the {@code Single}.
* @return the new {@code Single} instance
* @throws NullPointerException if {@code observable} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single fromObservable(@NonNull ObservableSource extends T> observable) {
Objects.requireNonNull(observable, "observable is null");
return RxJavaPlugins.onAssembly(new ObservableSingleSingle<>(observable, null));
}
/**
* Returns a {@code Single} that invokes passed supplier and emits its result
* for each individual {@link SingleObserver} that subscribes.
*
* Allows you to defer execution of passed function until a {@code SingleObserver} subscribes to the {@link Single}.
* It makes passed function "lazy".
* Result of the function invocation will be emitted by the {@link Single}.
*
*
*
* - Scheduler:
* - {@code fromSupplier} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the {@link Supplier} throws an exception, the respective {@link Throwable} is
* delivered to the downstream via {@link SingleObserver#onError(Throwable)},
* except when the downstream has disposed this {@code Single} source.
* In this latter case, the {@code Throwable} is delivered to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} as an {@link io.reactivex.rxjava3.exceptions.UndeliverableException UndeliverableException}.
*
*
*
* @param supplier
* function which execution should be deferred, it will be invoked when {@code SingleObserver} subscribes to the {@code Single}.
* @param
* the type of the item emitted by the {@code Single}.
* @return the new {@code Single} whose {@code SingleObserver}s' subscriptions trigger an invocation of the given function.
* @throws NullPointerException if {@code supplier} is {@code null}
* @see #defer(Supplier)
* @see #fromCallable(Callable)
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single fromSupplier(@NonNull Supplier extends T> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return RxJavaPlugins.onAssembly(new SingleFromSupplier<>(supplier));
}
/**
* Returns a {@code Single} that emits a specified item.
*
*
*
* To convert any object into a {@code Single} that emits that object, pass that object into the
* {@code just} method.
*
* - Scheduler:
* - {@code just} does not operate by default on a particular {@link Scheduler}.
*
*
* @param item
* the item to emit
* @param
* the type of that item
* @return the new {@code Single} that emits {@code item}
* @throws NullPointerException if {@code item} is {@code null}
* @see ReactiveX operators documentation: Just
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <@NonNull T> Single just(T item) {
Objects.requireNonNull(item, "item is null");
return RxJavaPlugins.onAssembly(new SingleJust<>(item));
}
/**
* Merges an {@link Iterable} sequence of {@link SingleSource} instances into a single {@link Flowable} sequence,
* running all {@code SingleSource}s at once.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code SingleSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Flowable} terminates with that {@code Throwable} and all other source {@code SingleSource}s are disposed.
* If more than one {@code SingleSource} signals an error, the resulting {@code Flowable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Flowable} has been cancelled or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(Iterable)} to merge sources and terminate only when all source {@code SingleSource}s
* have completed or failed with an error.
*
*
* @param the common and resulting value type
* @param sources the {@code Iterable} sequence of {@code SingleSource} sources
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.0
* @see #mergeDelayError(Iterable)
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable merge(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromIterable(sources).flatMapSingle(Functions.identity());
}
/**
* Merges a sequence of {@link SingleSource} instances emitted by a {@link Publisher} into a single {@link Flowable} sequence,
* running all {@code SingleSource}s at once.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code SingleSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Flowable} terminates with that {@code Throwable} and all other source {@code SingleSource}s are disposed.
* If more than one {@code SingleSource} signals an error, the resulting {@code Flowable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Flowable} has been cancelled or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(Publisher)} to merge sources and terminate only when all source {@code SingleSource}s
* have completed or failed with an error.
*
*
* @param the common and resulting value type
* @param sources the {@code Publisher} emitting a sequence of {@code SingleSource}s
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @see #mergeDelayError(Publisher)
* @since 2.0
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable merge(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new FlowableFlatMapSinglePublisher<>(sources, Functions.identity(), false, Integer.MAX_VALUE));
}
/**
* Flattens a {@link SingleSource} that emits a {@code SingleSingle} into a single {@code Single} that emits the item
* emitted by the nested {@code SingleSource}, without any transformation.
*
*
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - The resulting {@code Single} emits the outer source's or the inner {@code SingleSource}'s {@link Throwable} as is.
* Unlike the other {@code merge()} operators, this operator won't and can't produce a {@link CompositeException} because there is
* only one possibility for the outer or the inner {@code SingleSource} to emit an {@code onError} signal.
* Therefore, there is no need for a {@code mergeDelayError(SingleSource
>)} operator.
*
*
*
* @param the value type of the sources and the output
* @param source
* a {@code Single} that emits a {@code Single}
* @return the new {@code Single} that emits the item that is the result of flattening the {@code Single} emitted
* by {@code source}
* @throws NullPointerException if {@code source} is {@code null}
* @see ReactiveX operators documentation: Merge
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single merge(@NonNull SingleSource extends SingleSource extends T>> source) {
Objects.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new SingleFlatMap, T>(source, Functions.identity()));
}
/**
* Flattens two {@link SingleSource}s into one {@link Flowable} sequence, without any transformation.
*
*
*
* You can combine items emitted by multiple {@code SingleSource}s so that they appear as a single {@code Flowable}, by
* using the {@code merge} method.
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code SingleSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Flowable} terminates with that {@code Throwable} and all other source {@code SingleSource}s are disposed.
* If more than one {@code SingleSource} signals an error, the resulting {@code Flowable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Flowable} has been cancelled or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(SingleSource, SingleSource)} to merge sources and terminate only when all source {@code SingleSource}s
* have completed or failed with an error.
*
*
*
* @param the common value type
* @param source1
* a {@code SingleSource} to be merged
* @param source2
* a {@code SingleSource} to be merged
* @return the new {@code Flowable} that emits all of the items emitted by the source {@code SingleSource}s
* @throws NullPointerException if {@code source1} or {@code source2} is {@code null}
* @see ReactiveX operators documentation: Merge
* @see #mergeDelayError(SingleSource, SingleSource)
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable merge(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
return Flowable.fromArray(source1, source2).flatMapSingle(Functions.identity(), false, Integer.MAX_VALUE);
}
/**
* Flattens three {@link SingleSource}s into one {@link Flowable} sequence, without any transformation.
*
*
*
* You can combine items emitted by multiple {@code SingleSource}s so that they appear as a single {@code Flowable}, by
* the {@code merge} method.
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code SingleSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Flowable} terminates with that {@code Throwable} and all other source {@code SingleSource}s are disposed.
* If more than one {@code SingleSource} signals an error, the resulting {@code Flowable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Flowable} has been cancelled or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(SingleSource, SingleSource, SingleSource)} to merge sources and terminate only when all source {@code SingleSource}s
* have completed or failed with an error.
*
*
*
* @param the common value type
* @param source1
* a {@code SingleSource} to be merged
* @param source2
* a {@code SingleSource} to be merged
* @param source3
* a {@code SingleSource} to be merged
* @return the new {@code Flowable} that emits all of the items emitted by the source {@code SingleSource}s
* @throws NullPointerException if {@code source1}, {@code source2} or {@code source3} is {@code null}
* @see ReactiveX operators documentation: Merge
* @see #mergeDelayError(SingleSource, SingleSource, SingleSource)
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable merge(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2,
@NonNull SingleSource extends T> source3
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
return Flowable.fromArray(source1, source2, source3).flatMapSingle(Functions.identity(), false, Integer.MAX_VALUE);
}
/**
* Flattens four {@link SingleSource}s into one {@link Flowable} sequence, without any transformation.
*
*
*
* You can combine items emitted by multiple {@code SingleSource}s so that they appear as a single {@code Flowable}, by
* the {@code merge} method.
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code SingleSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Flowable} terminates with that {@code Throwable} and all other source {@code SingleSource}s are disposed.
* If more than one {@code SingleSource} signals an error, the resulting {@code Flowable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Flowable} has been cancelled or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(SingleSource, SingleSource, SingleSource, SingleSource)} to merge sources and terminate only when all source {@code SingleSource}s
* have completed or failed with an error.
*
*
*
* @param the common value type
* @param source1
* a {@code SingleSource} to be merged
* @param source2
* a {@code SingleSource} to be merged
* @param source3
* a {@code SingleSource} to be merged
* @param source4
* a {@code SingleSource} to be merged
* @return the new {@code Flowable} that emits all of the items emitted by the source {@code SingleSource}s
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3} or {@code source4} is {@code null}
* @see ReactiveX operators documentation: Merge
* @see #mergeDelayError(SingleSource, SingleSource, SingleSource, SingleSource)
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable merge(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2,
@NonNull SingleSource extends T> source3, @NonNull SingleSource extends T> source4
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
return Flowable.fromArray(source1, source2, source3, source4).flatMapSingle(Functions.identity(), false, Integer.MAX_VALUE);
}
/**
* Merges an array of {@link SingleSource} instances into a single {@link Flowable} sequence,
* running all {@code SingleSource}s at once.
*
*
*
* - Backpressure:
* - The operator honors backpressure from downstream.
* - Scheduler:
* - {@code mergeArray} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code SingleSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Flowable} terminates with that {@code Throwable} and all other source {@code SingleSource}s are disposed.
* If more than one {@code SingleSource} signals an error, the resulting {@code Flowable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Flowable} has been cancelled or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeArrayDelayError(SingleSource...)} to merge sources and terminate only when all source {@code SingleSource}s
* have completed or failed with an error.
*
*
* @param the common and resulting value type
* @param sources the array sequence of {@code SingleSource} sources
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @see #mergeArrayDelayError(SingleSource...)
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static <@NonNull T> Flowable mergeArray(SingleSource extends T>... sources) {
return Flowable.fromArray(sources).flatMapSingle(Functions.identity(), false, Math.max(1, sources.length));
}
/**
* Flattens an array of {@link SingleSource}s into one {@link Flowable}, in a way that allows a subscriber to receive all
* successfully emitted items from each of the source {@code SingleSource}s without being interrupted by an error
* notification from one of them.
*
*
*
* This behaves like {@link #merge(Publisher)} except that if any of the merged {@code SingleSource}s notify of an
* error via {@link Subscriber#onError onError}, {@code mergeArrayDelayError} will refrain from propagating that
* error notification until all of the merged {@code SingleSource}s have finished emitting items.
*
* Even if multiple merged {@code SingleSource}s send {@code onError} notifications, {@code mergeArrayDelayError} will only
* invoke the {@code onError} method of its subscribers once.
*
* - Backpressure:
* - The operator honors backpressure from downstream.
* - Scheduler:
* - {@code mergeArrayDelayError} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the common element base type
* @param sources
* the array of {@code SingleSource}s
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @see ReactiveX operators documentation: Merge
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
@NonNull
public static <@NonNull T> Flowable mergeArrayDelayError(@NonNull SingleSource extends T>... sources) {
return Flowable.fromArray(sources).flatMapSingle(Functions.identity(), true, Math.max(1, sources.length));
}
/**
* Merges an {@link Iterable} sequence of {@link SingleSource} instances into one {@link Flowable} sequence,
* running all {@code SingleSource}s at once and delaying any error(s) until all sources succeed or fail.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.1.9 - experimental
* @param the common and resulting value type
* @param sources the {@code Iterable} sequence of {@code SingleSource}s
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @see #merge(Iterable)
* @since 2.2
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable mergeDelayError(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources) {
return Flowable.fromIterable(sources).flatMapSingle(Functions.identity(), true, Integer.MAX_VALUE);
}
/**
* Merges a sequence of {@link SingleSource} instances emitted by a {@link Publisher} into a {@link Flowable} sequence,
* running all {@code SingleSource}s at once and delaying any error(s) until all sources succeed or fail.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.1.9 - experimental
* @param the common and resulting value type
* @param sources the {@code Flowable} sequence of {@code SingleSource}s
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 2.2
* @see #merge(Publisher)
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable mergeDelayError(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new FlowableFlatMapSinglePublisher<>(sources, Functions.identity(), true, Integer.MAX_VALUE));
}
/**
* Flattens two {@link SingleSource}s into one {@link Flowable}, without any transformation, delaying
* any error(s) until all sources succeed or fail.
*
*
*
* You can combine items emitted by multiple {@code SingleSource}s so that they appear as one {@code Flowable}, by
* using the {@code mergeDelayError} method.
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.1.9 - experimental
* @param the common value type
* @param source1
* a {@code SingleSource} to be merged
* @param source2
* a {@code SingleSource} to be merged
* @return the new {@code Flowable} that emits all of the items emitted by the source {@code SingleSource}s
* @throws NullPointerException if {@code source1} or {@code source2} is {@code null}
* @see ReactiveX operators documentation: Merge
* @see #merge(SingleSource, SingleSource)
* @since 2.2
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable mergeDelayError(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
return Flowable.fromArray(source1, source2).flatMapSingle(Functions.identity(), true, Integer.MAX_VALUE);
}
/**
* Flattens two {@link SingleSource}s into one {@link Flowable}, without any transformation, delaying
* any error(s) until all sources succeed or fail.
*
*
*
* You can combine items emitted by multiple {@code SingleSource}s so that they appear as one {@code Flowable}, by
* the {@code mergeDelayError} method.
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.1.9 - experimental
* @param the common value type
* @param source1
* a {@code SingleSource} to be merged
* @param source2
* a {@code SingleSource} to be merged
* @param source3
* a {@code SingleSource} to be merged
* @return the new {@code Flowable} that emits all of the items emitted by the source {@code SingleSource}s
* @throws NullPointerException if {@code source1}, {@code source2} or {@code source3} is {@code null}
* @see ReactiveX operators documentation: Merge
* @see #merge(SingleSource, SingleSource, SingleSource)
* @since 2.2
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable mergeDelayError(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2,
@NonNull SingleSource extends T> source3
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
return Flowable.fromArray(source1, source2, source3).flatMapSingle(Functions.identity(), true, Integer.MAX_VALUE);
}
/**
* Flattens two {@link SingleSource}s into one {@link Flowable}, without any transformation, delaying
* any error(s) until all sources succeed or fail.
*
*
*
* You can combine items emitted by multiple {@code SingleSource}s so that they appear as one {@code Flowable}, by
* the {@code mergeDelayError} method.
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.1.9 - experimental
* @param the common value type
* @param source1
* a {@code SingleSource} to be merged
* @param source2
* a {@code SingleSource} to be merged
* @param source3
* a {@code SingleSource} to be merged
* @param source4
* a {@code SingleSource} to be merged
* @return the new {@code Flowable} that emits all of the items emitted by the source {@code SingleSource}s
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3} or {@code source4} is {@code null}
* @see ReactiveX operators documentation: Merge
* @see #merge(SingleSource, SingleSource, SingleSource, SingleSource)
* @since 2.2
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable mergeDelayError(
@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2,
@NonNull SingleSource extends T> source3, @NonNull SingleSource extends T> source4
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
return Flowable.fromArray(source1, source2, source3, source4).flatMapSingle(Functions.identity(), true, Integer.MAX_VALUE);
}
/**
* Returns a singleton instance of a never-signaling {@code Single} (only calls {@code onSubscribe}).
*
*
*
* - Scheduler:
* - {@code never} does not operate by default on a particular {@link Scheduler}.
*
* @param the target value type
* @return the singleton never instance
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@SuppressWarnings("unchecked")
@NonNull
public static <@NonNull T> Single never() {
return RxJavaPlugins.onAssembly((Single) SingleNever.INSTANCE);
}
/**
* Signals success with 0L value after the given delay when a {@link SingleObserver} subscribes.
*
*
*
* - Scheduler:
* - {@code timer} operates by default on the {@code computation} {@link Scheduler}.
*
* @param delay the delay amount
* @param unit the time unit of the delay
* @return the new {@code Single} instance
* @throws NullPointerException if {@code unit} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
@NonNull
public static Single timer(long delay, @NonNull TimeUnit unit) {
return timer(delay, unit, Schedulers.computation());
}
/**
* Signals success with 0L value on the specified {@link Scheduler} after the given
* delay when a {@link SingleObserver} subscribes.
*
*
*
* - Scheduler:
* - you specify the {@code Scheduler} to signal on.
*
* @param delay the delay amount
* @param unit the time unit of the delay
* @param scheduler the {@code Scheduler} where the single 0L will be emitted
* @return the new {@code Single} instance
* @throws NullPointerException
* if {@code unit} is {@code null}, or
* if {@code scheduler} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public static Single timer(long delay, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
Objects.requireNonNull(unit, "unit is null");
Objects.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new SingleTimer(delay, unit, scheduler));
}
/**
* Compares two {@link SingleSource}s and emits {@code true} if they emit the same value (compared via {@link Object#equals(Object)}).
*
*
*
* - Scheduler:
* - {@code sequenceEqual} does not operate by default on a particular {@link Scheduler}.
*
* @param the common value type
* @param source1 the first {@code SingleSource} instance
* @param source2 the second {@code SingleSource} instance
* @return the new {@code Single} instance
* @throws NullPointerException if {@code source1} or {@code source2} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single sequenceEqual(@NonNull SingleSource extends T> source1, @NonNull SingleSource extends T> source2) { // NOPMD
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
return RxJavaPlugins.onAssembly(new SingleEquals<>(source1, source2));
}
/**
* Switches between {@link SingleSource}s emitted by the source {@link Publisher} whenever
* a new {@code SingleSource} is emitted, disposing the previously running {@code SingleSource},
* exposing the success items as a {@link Flowable} sequence.
*
*
*
* - Backpressure:
* - The {@code sources} {@code Publisher} is consumed in an unbounded manner (requesting {@link Long#MAX_VALUE}).
* The returned {@code Flowable} respects the backpressure from the downstream.
* - Scheduler:
* - {@code switchOnNext} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - The returned sequence fails with the first error signaled by the {@code sources} {@code Publisher}
* or the currently running {@code SingleSource}, disposing the rest. Late errors are
* forwarded to the global error handler via {@link RxJavaPlugins#onError(Throwable)}.
*
* @param the element type of the {@code SingleSource}s
* @param sources the {@code Publisher} sequence of inner {@code SingleSource}s to switch between
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
* @see #switchOnNextDelayError(Publisher)
* @see ReactiveX operators documentation: Switch
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable switchOnNext(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new FlowableSwitchMapSinglePublisher<>(sources, Functions.identity(), false));
}
/**
* Switches between {@link SingleSource}s emitted by the source {@link Publisher} whenever
* a new {@code SingleSource} is emitted, disposing the previously running {@code SingleSource},
* exposing the success items as a {@link Flowable} sequence and delaying all errors from
* all of them until all terminate.
*
*
*
* - Backpressure:
* - The {@code sources} {@code Publisher} is consumed in an unbounded manner (requesting {@link Long#MAX_VALUE}).
* The returned {@code Flowable} respects the backpressure from the downstream.
* - Scheduler:
* - {@code switchOnNextDelayError} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - The returned {@code Flowable} collects all errors emitted by either the {@code sources}
* {@code Publisher} or any inner {@code SingleSource} and emits them as a {@link CompositeException}
* when all sources terminate. If only one source ever failed, its error is emitted as-is at the end.
*
* @param the element type of the {@code SingleSource}s
* @param sources the {@code Publisher} sequence of inner {@code SingleSource}s to switch between
* @return the new {@code Flowable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
* @see #switchOnNext(Publisher)
* @see ReactiveX operators documentation: Switch
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Flowable switchOnNextDelayError(@NonNull Publisher<@NonNull ? extends SingleSource extends T>> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new FlowableSwitchMapSinglePublisher<>(sources, Functions.identity(), true));
}
/**
* Advanced use only: creates a {@code Single} instance without
* any safeguards by using a callback that is called with a {@link SingleObserver}.
*
*
*
* - Scheduler:
* - {@code unsafeCreate} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param onSubscribe the function that is called with the subscribing {@code SingleObserver}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code onSubscribe} is {@code null}
* @throws IllegalArgumentException if {@code source} is a subclass of {@code Single}; such
* instances don't need conversion and is possibly a port remnant from 1.x or one should use {@link #hide()}
* instead.
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single unsafeCreate(@NonNull SingleSource onSubscribe) {
Objects.requireNonNull(onSubscribe, "onSubscribe is null");
if (onSubscribe instanceof Single) {
throw new IllegalArgumentException("unsafeCreate(Single) should be upgraded");
}
return RxJavaPlugins.onAssembly(new SingleFromUnsafeSource<>(onSubscribe));
}
/**
* Allows using and disposing a resource while running a {@link SingleSource} instance generated from
* that resource (similar to a try-with-resources).
*
*
*
* - Scheduler:
* - {@code using} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type of the {@code SingleSource} generated
* @param the resource type
* @param resourceSupplier the {@link Supplier} called for each {@link SingleObserver} to generate a resource object
* @param sourceSupplier the function called with the returned resource
* object from {@code resourceSupplier} and should return a {@code SingleSource} instance
* to be run by the operator
* @param resourceCleanup the consumer of the generated resource that is called exactly once for
* that particular resource when the generated {@code SingleSource} terminates
* (successfully or with an error) or gets disposed.
* @return the new {@code Single} instance
* @throws NullPointerException if {@code resourceSupplier}, {@code sourceSupplier} and {@code resourceCleanup} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <@NonNull T, @NonNull U> Single using(@NonNull Supplier resourceSupplier,
@NonNull Function super U, ? extends SingleSource extends T>> sourceSupplier,
@NonNull Consumer super U> resourceCleanup) {
return using(resourceSupplier, sourceSupplier, resourceCleanup, true);
}
/**
* Allows using and disposing a resource while running a {@link SingleSource} instance generated from
* that resource (similar to a try-with-resources).
*
*
*
* - Scheduler:
* - {@code using} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type of the {@code SingleSource} generated
* @param the resource type
* @param resourceSupplier the {@link Supplier} called for each {@link SingleObserver} to generate a resource object
* @param sourceSupplier the function called with the returned resource
* object from {@code resourceSupplier} and should return a {@code SingleSource} instance
* to be run by the operator
* @param resourceCleanup the consumer of the generated resource that is called exactly once for
* that particular resource when the generated {@code SingleSource} terminates
* (successfully or with an error) or gets disposed.
* @param eager
* If {@code true} then resource disposal will happen either on a {@code dispose()} call before the upstream is disposed
* or just before the emission of a terminal event ({@code onSuccess} or {@code onError}).
* If {@code false} the resource disposal will happen either on a {@code dispose()} call after the upstream is disposed
* or just after the emission of a terminal event ({@code onSuccess} or {@code onError}).
* @return the new {@code Single} instance
* @throws NullPointerException if {@code resourceSupplier}, {@code sourceSupplier} or {@code resourceCleanup} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T, @NonNull U> Single using(
@NonNull Supplier resourceSupplier,
@NonNull Function super U, ? extends SingleSource extends T>> sourceSupplier,
@NonNull Consumer super U> resourceCleanup,
boolean eager) {
Objects.requireNonNull(resourceSupplier, "resourceSupplier is null");
Objects.requireNonNull(sourceSupplier, "sourceSupplier is null");
Objects.requireNonNull(resourceCleanup, "resourceCleanup is null");
return RxJavaPlugins.onAssembly(new SingleUsing<>(resourceSupplier, sourceSupplier, resourceCleanup, eager));
}
/**
* Wraps a {@link SingleSource} instance into a new {@code Single} instance if not already a {@code Single}
* instance.
*
*
*
* - Scheduler:
* - {@code wrap} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type
* @param source the source to wrap
* @return the new {@code Single} instance
* @throws NullPointerException if {@code source} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Single wrap(@NonNull SingleSource source) {
Objects.requireNonNull(source, "source is null");
if (source instanceof Single) {
return RxJavaPlugins.onAssembly((Single)source);
}
return RxJavaPlugins.onAssembly(new SingleFromUnsafeSource<>(source));
}
/**
* Waits until all {@link SingleSource} sources provided by the {@link Iterable} sequence signal a success
* value and calls a zipper function with an array of these values to return a result
* to be emitted to the downstream.
*
* If the {@code Iterable} of {@code SingleSource}s is empty a {@link NoSuchElementException} error is signaled after subscription.
*
* Note on method signature: since Java doesn't allow creating a generic array with {@code new T[]}, the
* implementation of this operator has to create an {@code Object[]} instead. Unfortunately, a
* {@code Function} passed to the method would trigger a {@link ClassCastException}.
*
*
*
*
* If any of the {@code SingleSources} signal an error, all other {@code SingleSource}s get disposed and the
* error emitted to downstream immediately.
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
* @param the common value type
* @param the result value type
* @param sources the {@code Iterable} sequence of {@code SingleSource} instances. An empty sequence will result in an
* {@code onError} signal of {@code NoSuchElementException}.
* @param zipper the function that receives an array with values from each {@code SingleSource}
* and should return a value to be emitted to downstream
* @return the new {@code Single} instance
* @throws NullPointerException if {@code zipper} or {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T, @NonNull R> Single zip(@NonNull Iterable<@NonNull ? extends SingleSource extends T>> sources,
@NonNull Function super Object[], ? extends R> zipper) {
Objects.requireNonNull(zipper, "zipper is null");
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new SingleZipIterable<>(sources, zipper));
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to two items emitted by
* two other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull BiFunction super T1, ? super T2, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2);
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to three items emitted
* by three other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the third source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param source3
* a third source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull T3, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull SingleSource extends T3> source3,
@NonNull Function3 super T1, ? super T2, ? super T3, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2, source3);
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to four items
* emitted by four other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the third source {@code SingleSource}'s value type
* @param the fourth source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param source3
* a third source {@code SingleSource}
* @param source4
* a fourth source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3}, {@code source4} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull T3, @NonNull T4, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull SingleSource extends T3> source3, @NonNull SingleSource extends T4> source4,
@NonNull Function4 super T1, ? super T2, ? super T3, ? super T4, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2, source3, source4);
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to five items
* emitted by five other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the third source {@code SingleSource}'s value type
* @param the fourth source {@code SingleSource}'s value type
* @param the fifth source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param source3
* a third source {@code SingleSource}
* @param source4
* a fourth source {@code SingleSource}
* @param source5
* a fifth source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3}, {@code source4}
* {@code source5} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull T3, @NonNull T4, @NonNull T5, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull SingleSource extends T3> source3, @NonNull SingleSource extends T4> source4,
@NonNull SingleSource extends T5> source5,
@NonNull Function5 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
Objects.requireNonNull(source5, "source5 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2, source3, source4, source5);
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to six items
* emitted by six other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the third source {@code SingleSource}'s value type
* @param the fourth source {@code SingleSource}'s value type
* @param the fifth source {@code SingleSource}'s value type
* @param the sixth source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param source3
* a third source {@code SingleSource}
* @param source4
* a fourth source {@code SingleSource}
* @param source5
* a fifth source {@code SingleSource}
* @param source6
* a sixth source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3}, {@code source4}
* {@code source5}, {@code source6} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull T3, @NonNull T4, @NonNull T5, @NonNull T6, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull SingleSource extends T3> source3, @NonNull SingleSource extends T4> source4,
@NonNull SingleSource extends T5> source5, @NonNull SingleSource extends T6> source6,
@NonNull Function6 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
Objects.requireNonNull(source5, "source5 is null");
Objects.requireNonNull(source6, "source6 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2, source3, source4, source5, source6);
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to seven items
* emitted by seven other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the third source {@code SingleSource}'s value type
* @param the fourth source {@code SingleSource}'s value type
* @param the fifth source {@code SingleSource}'s value type
* @param the sixth source {@code SingleSource}'s value type
* @param the seventh source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param source3
* a third source {@code SingleSource}
* @param source4
* a fourth source {@code SingleSource}
* @param source5
* a fifth source {@code SingleSource}
* @param source6
* a sixth source {@code SingleSource}
* @param source7
* a seventh source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3}, {@code source4}
* {@code source5}, {@code source6}, {@code source7} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull T3, @NonNull T4, @NonNull T5, @NonNull T6, @NonNull T7, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull SingleSource extends T3> source3, @NonNull SingleSource extends T4> source4,
@NonNull SingleSource extends T5> source5, @NonNull SingleSource extends T6> source6,
@NonNull SingleSource extends T7> source7,
@NonNull Function7 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
Objects.requireNonNull(source5, "source5 is null");
Objects.requireNonNull(source6, "source6 is null");
Objects.requireNonNull(source7, "source7 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2, source3, source4, source5, source6, source7);
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to eight items
* emitted by eight other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the third source {@code SingleSource}'s value type
* @param the fourth source {@code SingleSource}'s value type
* @param the fifth source {@code SingleSource}'s value type
* @param the sixth source {@code SingleSource}'s value type
* @param the seventh source {@code SingleSource}'s value type
* @param the eighth source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param source3
* a third source {@code SingleSource}
* @param source4
* a fourth source {@code SingleSource}
* @param source5
* a fifth source {@code SingleSource}
* @param source6
* a sixth source {@code SingleSource}
* @param source7
* a seventh source {@code SingleSource}
* @param source8
* an eighth source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3}, {@code source4}
* {@code source5}, {@code source6}, {@code source7}, {@code source8} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull T3, @NonNull T4, @NonNull T5, @NonNull T6, @NonNull T7, @NonNull T8, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull SingleSource extends T3> source3, @NonNull SingleSource extends T4> source4,
@NonNull SingleSource extends T5> source5, @NonNull SingleSource extends T6> source6,
@NonNull SingleSource extends T7> source7, @NonNull SingleSource extends T8> source8,
@NonNull Function8 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
Objects.requireNonNull(source5, "source5 is null");
Objects.requireNonNull(source6, "source6 is null");
Objects.requireNonNull(source7, "source7 is null");
Objects.requireNonNull(source8, "source8 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2, source3, source4, source5, source6, source7, source8);
}
/**
* Returns a {@code Single} that emits the results of a specified combiner function applied to nine items
* emitted by nine other {@link SingleSource}s.
*
*
*
* - Scheduler:
* - {@code zip} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the first source {@code SingleSource}'s value type
* @param the second source {@code SingleSource}'s value type
* @param the third source {@code SingleSource}'s value type
* @param the fourth source {@code SingleSource}'s value type
* @param the fifth source {@code SingleSource}'s value type
* @param the sixth source {@code SingleSource}'s value type
* @param the seventh source {@code SingleSource}'s value type
* @param the eighth source {@code SingleSource}'s value type
* @param the ninth source {@code SingleSource}'s value type
* @param the result value type
* @param source1
* the first source {@code SingleSource}
* @param source2
* a second source {@code SingleSource}
* @param source3
* a third source {@code SingleSource}
* @param source4
* a fourth source {@code SingleSource}
* @param source5
* a fifth source {@code SingleSource}
* @param source6
* a sixth source {@code SingleSource}
* @param source7
* a seventh source {@code SingleSource}
* @param source8
* an eighth source {@code SingleSource}
* @param source9
* a ninth source {@code SingleSource}
* @param zipper
* a function that, when applied to the item emitted by each of the source {@code SingleSource}s, results in an
* item that will be emitted by the resulting {@code Single}
* @return the new {@code Single} that emits the zipped results
* @throws NullPointerException if {@code source1}, {@code source2}, {@code source3}, {@code source4}
* {@code source5}, {@code source6}, {@code source7}, {@code source8},
* {@code source9} or {@code zipper} is {@code null}
* @see ReactiveX operators documentation: Zip
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T1, @NonNull T2, @NonNull T3, @NonNull T4, @NonNull T5, @NonNull T6, @NonNull T7, @NonNull T8, @NonNull T9, @NonNull R> Single zip(
@NonNull SingleSource extends T1> source1, @NonNull SingleSource extends T2> source2,
@NonNull SingleSource extends T3> source3, @NonNull SingleSource extends T4> source4,
@NonNull SingleSource extends T5> source5, @NonNull SingleSource extends T6> source6,
@NonNull SingleSource extends T7> source7, @NonNull SingleSource extends T8> source8,
@NonNull SingleSource extends T9> source9,
@NonNull Function9 super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? extends R> zipper
) {
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
Objects.requireNonNull(source3, "source3 is null");
Objects.requireNonNull(source4, "source4 is null");
Objects.requireNonNull(source5, "source5 is null");
Objects.requireNonNull(source6, "source6 is null");
Objects.requireNonNull(source7, "source7 is null");
Objects.requireNonNull(source8, "source8 is null");
Objects.requireNonNull(source9, "source9 is null");
Objects.requireNonNull(zipper, "zipper is null");
return zipArray(Functions.toFunction(zipper), source1, source2, source3, source4, source5, source6, source7, source8, source9);
}
/**
* Waits until all {@link SingleSource} sources provided via an array signal a success
* value and calls a zipper function with an array of these values to return a result
* to be emitted to downstream.
*
*
*
* If the array of {@code SingleSource}s is empty a {@link NoSuchElementException} error is signaled immediately.
*
* Note on method signature: since Java doesn't allow creating a generic array with {@code new T[]}, the
* implementation of this operator has to create an {@code Object[]} instead. Unfortunately, a
* {@code Function} passed to the method would trigger a {@link ClassCastException}.
*
* If any of the {@code SingleSource}s signal an error, all other {@code SingleSource}s get disposed and the
* error emitted to downstream immediately.
*
* - Scheduler:
* - {@code zipArray} does not operate by default on a particular {@link Scheduler}.
*
* @param the common value type
* @param the result value type
* @param sources the array of {@code SingleSource} instances. An empty sequence will result in an
* {@code onError} signal of {@code NoSuchElementException}.
* @param zipper the function that receives an array with values from each {@code SingleSource}
* and should return a value to be emitted to downstream
* @return the new {@code Single} instance
* @throws NullPointerException if {@code zipper} or {@code sources} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static <@NonNull T, @NonNull R> Single zipArray(@NonNull Function super Object[], ? extends R> zipper, @NonNull SingleSource extends T>... sources) {
Objects.requireNonNull(zipper, "zipper is null");
Objects.requireNonNull(sources, "sources is null");
if (sources.length == 0) {
return error(new NoSuchElementException());
}
return RxJavaPlugins.onAssembly(new SingleZipArray<>(sources, zipper));
}
/**
* Signals the event of this or the other {@link SingleSource} whichever signals first.
*
*
*
* - Scheduler:
* - {@code ambWith} does not operate by default on a particular {@link Scheduler}.
*
* @param other the other {@code SingleSource} to race for the first emission of success or error
* @return the new {@code Single} instance. A subscription to this provided source will occur after subscribing
* to the current source.
* @throws NullPointerException if {@code other} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Single ambWith(@NonNull SingleSource extends T> other) {
Objects.requireNonNull(other, "other is null");
return ambArray(this, other);
}
/**
* Hides the identity of the current {@code Single}, including the {@link Disposable} that is sent
* to the downstream via {@code onSubscribe()}.
*
*
*
* - Scheduler:
* - {@code hide} does not operate by default on a particular {@link Scheduler}.
*
* @return the new {@code Single} instance
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Single hide() {
return RxJavaPlugins.onAssembly(new SingleHide<>(this));
}
/**
* Transform a {@code Single} by applying a particular {@link SingleTransformer} function to it.
*
*
*
* This method operates on the {@code Single} itself whereas {@link #lift} operates on {@link SingleObserver}s.
*
* If the operator you are creating is designed to act on the individual item emitted by a {@code Single}, use
* {@link #lift}. If your operator is designed to transform the current {@code Single} as a whole (for instance, by
* applying a particular set of existing RxJava operators to it) use {@code compose}.
*
* - Scheduler:
* - {@code compose} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the value type of the single returned by the transformer function
* @param transformer the transformer function, not {@code null}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code transformer} is {@code null}
* @see RxJava wiki: Implementing Your Own Operators
*/
@SuppressWarnings("unchecked")
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final <@NonNull R> Single compose(@NonNull SingleTransformer super T, ? extends R> transformer) {
return wrap(((SingleTransformer) Objects.requireNonNull(transformer, "transformer is null")).apply(this));
}
/**
* Stores the success value or exception from the current {@code Single} and replays it to late {@link SingleObserver}s.
*
*
*
* The returned {@code Single} subscribes to the current {@code Single} when the first {@code SingleObserver} subscribes.
*
* - Scheduler:
* - {@code cache} does not operate by default on a particular {@link Scheduler}.
*
*
* @return the new {@code Single} instance
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Single cache() {
return RxJavaPlugins.onAssembly(new SingleCache<>(this));
}
/**
* Casts the success value of the current {@code Single} into the target type or signals a
* {@link ClassCastException} if not compatible.
*
*
*
* - Scheduler:
* - {@code cast} does not operate by default on a particular {@link Scheduler}.
*
* @param the target type
* @param clazz the type token to use for casting the success result from the current {@code Single}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code clazz} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull U> Single cast(@NonNull Class extends U> clazz) {
Objects.requireNonNull(clazz, "clazz is null");
return map(Functions.castFunction(clazz));
}
/**
* Returns a {@code Single} that is based on applying a specified function to the item emitted by the current {@code Single},
* where that function returns a {@link SingleSource}.
*
*
*
* The operator is an alias for {@link #flatMap(Function)}
*
* - Scheduler:
* - {@code concatMap} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the result value type
* @param mapper
* a function that, when applied to the item emitted by the current {@code Single}, returns a {@code SingleSource}
* @return the new {@code Single} returned from {@code mapper} when applied to the item emitted by the current {@code Single}
* @throws NullPointerException if {@code mapper} is {@code null}
* @see ReactiveX operators documentation: FlatMap
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull R> Single concatMap(@NonNull Function super T, ? extends SingleSource extends R>> mapper) {
Objects.requireNonNull(mapper, "mapper is null");
return RxJavaPlugins.onAssembly(new SingleFlatMap<>(this, mapper));
}
/**
* Returns a {@link Completable} that completes based on applying a specified function to the item emitted by the
* current {@code Single}, where that function returns a {@link CompletableSource}.
*
*
*
* The operator is an alias for {@link #flatMapCompletable(Function)}.
*
* - Scheduler:
* - {@code concatMapCompletable} does not operate by default on a particular {@link Scheduler}.
*
*
* @param mapper
* a function that, when applied to the item emitted by the current {@code Single}, returns a
* {@code CompletableSource}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code mapper} is {@code null}
* @see ReactiveX operators documentation: FlatMap
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable concatMapCompletable(@NonNull Function super T, ? extends CompletableSource> mapper) {
return flatMapCompletable(mapper);
}
/**
* Returns a {@link Maybe} that is based on applying a specified function to the item emitted by the current {@code Single},
* where that function returns a {@link MaybeSource}.
*
*
*
* The operator is an alias for {@link #flatMapMaybe(Function)}.
*
* - Scheduler:
* - {@code concatMapMaybe} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the result value type
* @param mapper
* a function that, when applied to the item emitted by the current {@code Single}, returns a {@code MaybeSource}
* @return the new {@code Maybe} returned from {@code mapper} when applied to the item emitted by the current {@code Single}
* @throws NullPointerException if {@code mapper} is {@code null}
* @see ReactiveX operators documentation: FlatMap
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull R> Maybe concatMapMaybe(@NonNull Function super T, ? extends MaybeSource extends R>> mapper) {
return flatMapMaybe(mapper);
}
/**
* Returns a {@link Flowable} that emits the item emitted by the current {@code Single}, then the item emitted by the
* specified {@link SingleSource}.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer.
* - Scheduler:
* - {@code concatWith} does not operate by default on a particular {@link Scheduler}.
*
*
* @param other
* a {@code SingleSource} to be concatenated after the current
* @return the new {@code Flowable} that emits the item emitted by the current {@code Single}, followed by the item emitted by
* {@code other}
* @throws NullPointerException if {@code other} is {@code null}
* @see ReactiveX operators documentation: Concat
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Flowable concatWith(@NonNull SingleSource extends T> other) {
return concat(this, other);
}
/**
* Delays the emission of the success signal from the current {@code Single} by the specified amount.
* An error signal will not be delayed.
*
*
*
* - Scheduler:
* - {@code delay} operates by default on the {@code computation} {@link Scheduler}.
*
*
* @param time the amount of time the success signal should be delayed for
* @param unit the time unit
* @return the new {@code Single} instance
* @since 2.0
* @throws NullPointerException if {@code unit} is {@code null}
* @see #delay(long, TimeUnit, boolean)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
@NonNull
public final Single delay(long time, @NonNull TimeUnit unit) {
return delay(time, unit, Schedulers.computation(), false);
}
/**
* Delays the emission of the success or error signal from the current {@code Single} by the specified amount.
*
*
*
* - Scheduler:
* - {@code delay} operates by default on the {@code computation} {@link Scheduler}.
*
* History: 2.1.5 - experimental
* @param time the amount of time the success or error signal should be delayed for
* @param unit the time unit
* @param delayError if {@code true}, both success and error signals are delayed. if {@code false}, only success signals are delayed.
* @return the new {@code Single} instance
* @throws NullPointerException if {@code unit} is {@code null}
* @since 2.2
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
@NonNull
public final Single delay(long time, @NonNull TimeUnit unit, boolean delayError) {
return delay(time, unit, Schedulers.computation(), delayError);
}
/**
* Delays the emission of the success signal from the current {@code Single} by the specified amount.
* An error signal will not be delayed.
*
*
*
* - Scheduler:
* - you specify the {@link Scheduler} where the non-blocking wait and emission happens
*
*
* @param time the amount of time the success signal should be delayed for
* @param unit the time unit
* @param scheduler the target scheduler to use for the non-blocking wait and emission
* @return the new {@code Single} instance
* @throws NullPointerException
* if {@code unit} is {@code null}, or
* if {@code scheduler} is {@code null}
* @since 2.0
* @see #delay(long, TimeUnit, Scheduler, boolean)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
@NonNull
public final Single delay(long time, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
return delay(time, unit, scheduler, false);
}
/**
* Delays the emission of the success or error signal from the current {@code Single} by the specified amount.
*
*
*
* - Scheduler:
* - you specify the {@link Scheduler} where the non-blocking wait and emission happens
*
* History: 2.1.5 - experimental
* @param time the amount of time the success or error signal should be delayed for
* @param unit the time unit
* @param scheduler the target scheduler to use for the non-blocking wait and emission
* @param delayError if {@code true}, both success and error signals are delayed. if {@code false}, only success signals are delayed.
* @return the new {@code Single} instance
* @throws NullPointerException
* if {@code unit} is {@code null}, or
* if {@code scheduler} is {@code null}
* @since 2.2
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Single delay(long time, @NonNull TimeUnit unit, @NonNull Scheduler scheduler, boolean delayError) {
Objects.requireNonNull(unit, "unit is null");
Objects.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new SingleDelay<>(this, time, unit, scheduler, delayError));
}
/**
* Delays the actual subscription to the current {@code Single} until the given other {@link CompletableSource}
* completes.
*
*
*
If the delaying source signals an error, that error is re-emitted and no subscription
* to the current {@code Single} happens.
*
* - Scheduler:
* - {@code delaySubscription} does not operate by default on a particular {@link Scheduler}.
*
* @param subscriptionIndicator the {@code CompletableSource} that has to complete before the subscription to the
* current {@code Single} happens
* @return the new {@code Single} instance
* @throws NullPointerException if {@code subscriptionIndicator} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Single delaySubscription(@NonNull CompletableSource subscriptionIndicator) {
Objects.requireNonNull(subscriptionIndicator, "subscriptionIndicator is null");
return RxJavaPlugins.onAssembly(new SingleDelayWithCompletable<>(this, subscriptionIndicator));
}
/**
* Delays the actual subscription to the current {@code Single} until the given other {@link SingleSource}
* signals success.
*
*
*
If the delaying source signals an error, that error is re-emitted and no subscription
* to the current {@code Single} happens.
*
* - Scheduler:
* - {@code delaySubscription} does not operate by default on a particular {@link Scheduler}.
*
* @param the element type of the other source
* @param subscriptionIndicator the {@code SingleSource} that has to complete before the subscription to the
* current {@code Single} happens
* @return the new {@code Single} instance
* @throws NullPointerException if {@code subscriptionIndicator} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull U> Single delaySubscription(@NonNull SingleSource subscriptionIndicator) {
Objects.requireNonNull(subscriptionIndicator, "subscriptionIndicator is null");
return RxJavaPlugins.onAssembly(new SingleDelayWithSingle<>(this, subscriptionIndicator));
}
/**
* Delays the actual subscription to the current {@code Single} until the given other {@link ObservableSource}
* signals its first value or completes.
*
*
*
If the delaying source signals an error, that error is re-emitted and no subscription
* to the current {@code Single} happens.
*
* - Scheduler:
* - {@code delaySubscription} does not operate by default on a particular {@link Scheduler}.
*
* @param the element type of the other source
* @param subscriptionIndicator the {@code ObservableSource} that has to signal a value or complete before the
* subscription to the current {@code Single} happens
* @return the new {@code Single} instance
* @throws NullPointerException if {@code subscriptionIndicator} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull U> Single delaySubscription(@NonNull ObservableSource subscriptionIndicator) {
Objects.requireNonNull(subscriptionIndicator, "subscriptionIndicator is null");
return RxJavaPlugins.onAssembly(new SingleDelayWithObservable<>(this, subscriptionIndicator));
}
/**
* Delays the actual subscription to the current {@code Single} until the given other {@link Publisher}
* signals its first value or completes.
*
*
*
If the delaying source signals an error, that error is re-emitted and no subscription
* to the current {@code Single} happens.
*
The other source is consumed in an unbounded manner (requesting {@link Long#MAX_VALUE} from it).
*
* - Backpressure:
* - The {@code other} publisher is consumed in an unbounded fashion but will be
* cancelled after the first item it produced.
* - Scheduler:
* - {@code delaySubscription} does not operate by default on a particular {@link Scheduler}.
*
* @param the element type of the other source
* @param subscriptionIndicator the {@code Publisher} that has to signal a value or complete before the
* subscription to the current {@code Single} happens
* @return the new {@code Single} instance
* @throws NullPointerException if {@code subscriptionIndicator} is {@code null}
* @since 2.0
*/
@BackpressureSupport(BackpressureKind.FULL)
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull U> Single delaySubscription(@NonNull Publisher subscriptionIndicator) {
Objects.requireNonNull(subscriptionIndicator, "subscriptionIndicator is null");
return RxJavaPlugins.onAssembly(new SingleDelayWithPublisher<>(this, subscriptionIndicator));
}
/**
* Delays the actual subscription to the current {@code Single} until the given time delay elapsed.
*
*
*
* - Scheduler:
* - {@code delaySubscription} does by default subscribe to the current {@code Single}
* on the {@code computation} {@link Scheduler} after the delay.
*
* @param time the time amount to wait with the subscription
* @param unit the time unit of the waiting
* @return the new {@code Single} instance
* @throws NullPointerException if {@code unit} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
@NonNull
public final Single delaySubscription(long time, @NonNull TimeUnit unit) {
return delaySubscription(time, unit, Schedulers.computation());
}
/**
* Delays the actual subscription to the current {@code Single} until the given time delay elapsed.
*
*
*
* - Scheduler:
* - {@code delaySubscription} does by default subscribe to the current {@code Single}
* on the {@link Scheduler} you provided, after the delay.
*
* @param time the time amount to wait with the subscription
* @param unit the time unit of the waiting
* @param scheduler the {@code Scheduler} to wait on and subscribe on to the current {@code Single}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code unit} or {@code scheduler} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
@NonNull
public final Single delaySubscription(long time, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
return delaySubscription(Observable.timer(time, unit, scheduler));
}
/**
* Maps the {@link Notification} success value of the current {@code Single} back into normal
* {@code onSuccess}, {@code onError} or {@code onComplete} signals as a
* {@link Maybe} source.
*
*
*
* The intended use of the {@code selector} function is to perform a
* type-safe identity mapping (see example) on a source that is already of type
* {@code Notification}. The Java language doesn't allow
* limiting instance methods to a certain generic argument shape, therefore,
* a function is used to ensure the conversion remains type safe.
*
* - Scheduler:
* - {@code dematerialize} does not operate by default on a particular {@link Scheduler}.
*
*
* Example:
*
* Single.just(Notification.createOnNext(1))
* .dematerialize(notification -> notification)
* .test()
* .assertResult(1);
*
* History: 2.2.4 - experimental
* @param the result type
* @param selector the function called with the success item and should
* return a {@code Notification} instance.
* @return the new {@code Maybe} instance
* @throws NullPointerException if {@code selector} is {@code null}
* @since 3.0.0
* @see #materialize()
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull R> Maybe dematerialize(@NonNull Function super T, @NonNull Notification> selector) {
Objects.requireNonNull(selector, "selector is null");
return RxJavaPlugins.onAssembly(new SingleDematerialize<>(this, selector));
}
/**
* Calls the specified consumer with the success item after this item has been emitted to the downstream.
*
*
*
* Note that the {@code doAfterSuccess} action is shared between subscriptions and as such
* should be thread-safe.
*
* - Scheduler:
* - {@code doAfterSuccess} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.0.1 - experimental
* @param onAfterSuccess the {@link Consumer} that will be called after emitting an item from upstream to the downstream
* @return the new {@code Single} instance
* @throws NullPointerException if {@code onAfterSuccess} is {@code null}
* @since 2.1
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Single doAfterSuccess(@NonNull Consumer super T> onAfterSuccess) {
Objects.requireNonNull(onAfterSuccess, "onAfterSuccess is null");
return RxJavaPlugins.onAssembly(new SingleDoAfterSuccess<>(this, onAfterSuccess));
}
/**
* Registers an {@link Action} to be called after this {@code Single} invokes either {@code onSuccess} or {@code onError}.
*
*
*
* Note that the {@code doAfterTerminate} action is shared between subscriptions and as such
* should be thread-safe.
*
*
* - Scheduler:
* - {@code doAfterTerminate} does not operate by default on a particular {@link Scheduler}.
*
*
* History: 2.0.6 - experimental
* @param onAfterTerminate
* an {@code Action} to be invoked when the current {@code Single} finishes
* @return the new {@code Single} that emits the same items as the current {@code Single}, then invokes the
* {@code Action}
* @throws NullPointerException if {@code onAfterTerminate} is {@code null}
* @see ReactiveX operators documentation: Do
* @since 2.1
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Single doAfterTerminate(@NonNull Action onAfterTerminate) {
Objects.requireNonNull(onAfterTerminate, "onAfterTerminate is null");
return RxJavaPlugins.onAssembly(new SingleDoAfterTerminate<>(this, onAfterTerminate));
}
/**
* Calls the specified action after this {@code Single} signals {@code onSuccess} or {@code onError} or gets disposed by
* the downstream.
* In case of a race between a terminal event and a dispose call, the provided {@code onFinally} action
* is executed once per subscription.
*
Note that the {@code onFinally} action is shared between subscriptions and as such
* should be thread-safe.
*
*
*
*
* - Scheduler:
* - {@code doFinally} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.0.1 - experimental
* @param onFinally the action called when this {@code Single} terminates or gets disposed
* @return the new {@code Single} instance
* @throws NullPointerException if {@code onFinally} is {@code null}
* @since 2.1
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Single doFinally(@NonNull Action onFinally) {
Objects.requireNonNull(onFinally, "onFinally is null");
return RxJavaPlugins.onAssembly(new SingleDoFinally<>(this, onFinally));
}
/**
* Calls the appropriate {@code onXXX} method (shared between all {@link SingleObserver}s) for the lifecycle events of
* the sequence (subscription, disposal).
*
*
*
* - Scheduler:
* - {@code doOnLifecycle} does not operate by default on a particular {@link Scheduler}.
*
*
* @param onSubscribe
* a {@link Consumer} called with the {@link Disposable} sent via {@link SingleObserver#onSubscribe(Disposable)}
* @param onDispose
* called when the downstream disposes the {@code Disposable} via {@code dispose()}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code onSubscribe} or {@code onDispose} is {@code null}
* @see ReactiveX operators documentation: Do
* @since 3.0.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Single doOnLifecycle(@NonNull Consumer super Disposable> onSubscribe, @NonNull Action onDispose) {
Objects.requireNonNull(onSubscribe, "onSubscribe is null");
Objects.requireNonNull(onDispose, "onDispose is null");
return RxJavaPlugins.onAssembly(new SingleDoOnLifecycle<>(this, onSubscribe, onDispose));
}
/**
* Calls the shared consumer with the {@link Disposable} sent through the {@code onSubscribe} for each
* {@link SingleObserver} that subscribes to the current {@code Single}.
*
*
*
*
* - Scheduler:
* - {@code doOnSubscribe} does not operate by default on a particular {@link Scheduler}.
*
* @param onSubscribe the consumer called with the {@code Disposable} sent via {@code onSubscribe}
* @return the new {@code Single} instance
* @throws NullPointerException if {@code onSubscribe} is {@code null}
* @since 2.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Single doOnSubscribe(@NonNull Consumer super Disposable> onSubscribe) {
Objects.requireNonNull(onSubscribe, "onSubscribe is null");
return RxJavaPlugins.onAssembly(new SingleDoOnSubscribe<>(this, onSubscribe));
}
/**
* Returns a {@code Single} instance that calls the given {@code onTerminate} callback
* just before this {@code Single} completes normally or with an exception.
*
*
*
* This differs from {@code doAfterTerminate} in that this happens before the {@code onSuccess} or
* {@code onError} notification.
*
*