All Downloads are FREE. Search and download functionalities are using the official Maven repository.

hu.akarnokd.rxjava2.Observable Maven / Gradle / Ivy

/**
 * Copyright 2015 David Karnok and Netflix, Inc.
 * 
 * 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 hu.akarnokd.rxjava2;


import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

import org.reactivestreams.*;

import hu.akarnokd.rxjava2.annotations.*;
import hu.akarnokd.rxjava2.disposables.Disposable;
import hu.akarnokd.rxjava2.functions.*;
import hu.akarnokd.rxjava2.internal.functions.Functions;
import hu.akarnokd.rxjava2.internal.functions.Objects;
import hu.akarnokd.rxjava2.internal.operators.*;
import hu.akarnokd.rxjava2.internal.subscribers.*;
import hu.akarnokd.rxjava2.internal.subscriptions.EmptySubscription;
import hu.akarnokd.rxjava2.observables.*;
import hu.akarnokd.rxjava2.plugins.RxJavaPlugins;
import hu.akarnokd.rxjava2.schedulers.*;
import hu.akarnokd.rxjava2.subscribers.*;

public class Observable implements Publisher {
    /**
     * Interface to map/wrap a downstream subscriber to an upstream subscriber.
     *
     * @param  the value type of the downstream
     * @param  the value type of the upstream
     */
    public interface Operator extends Function, Subscriber> {

    }
    
    /**
     * Interface to compose observables.
     *
     * @param  the upstream value type
     * @param  the downstream value type
     */
    public interface Transformer extends Function, Publisher> {
        
    }

    /** The default buffer size. */
    static final int BUFFER_SIZE;
    static {
        BUFFER_SIZE = Math.max(16, Integer.getInteger("rx2.buffer-size", 128));
    }

    /** An empty observable instance as there is no need to instantiate this more than once. */
    static final Observable EMPTY = create(PublisherEmptySource.INSTANCE);

    /** A never observable instance as there is no need to instantiate this more than once. */
    static final Observable NEVER = create(new Publisher() {
        @Override
        public void subscribe(Subscriber s) {
            s.onSubscribe(EmptySubscription.INSTANCE);
        }
    });

    public static  Observable amb(Iterable> sources) {
        Objects.requireNonNull(sources, "sources is null");
        return create(new PublisherAmb(null, sources));
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable amb(Publisher... sources) {
        Objects.requireNonNull(sources, "sources is null");
        int len = sources.length;
        if (len == 0) {
            return empty();
        } else
        if (len == 1) {
            return fromPublisher(sources[0]);
        }
        return create(new PublisherAmb(sources, null));
    }

    public static int bufferSize() {
        return BUFFER_SIZE;
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(Function combiner, boolean delayError, int bufferSize, Publisher... sources) {
        return combineLatest(sources, combiner, delayError, bufferSize);
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(Iterable> sources, Function combiner) {
        return combineLatest(sources, combiner, false, bufferSize());
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(Iterable> sources, Function combiner, boolean delayError) {
        return combineLatest(sources, combiner, delayError, bufferSize());
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(Iterable> sources, Function combiner, boolean delayError, int bufferSize) {
        Objects.requireNonNull(sources, "sources is null");
        Objects.requireNonNull(combiner, "combiner is null");
        validateBufferSize(bufferSize);
        
        // the queue holds a pair of values so we need to double the capacity
        int s = bufferSize << 1;
        return create(new PublisherCombineLatest(null, sources, combiner, s, delayError));
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(Publisher[] sources, Function combiner) {
        return combineLatest(sources, combiner, false, bufferSize());
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(Publisher[] sources, Function combiner, boolean delayError) {
        return combineLatest(sources, combiner, delayError, bufferSize());
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(Publisher[] sources, Function combiner, boolean delayError, int bufferSize) {
        validateBufferSize(bufferSize);
        Objects.requireNonNull(combiner, "combiner is null");
        if (sources.length == 0) {
            return empty();
        }
        // the queue holds a pair of values so we need to double the capacity
        int s = bufferSize << 1;
        return create(new PublisherCombineLatest(sources, null, combiner, s, delayError));
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            BiFunction combiner) {
        Function f = Functions.toFunction(combiner);
        return combineLatest(f, false, bufferSize(), p1, p2);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            Publisher p3, 
            Function3 combiner) {
        return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Function4 combiner) {
        return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5,
            Function5 combiner) {
        return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6,
            Function6 combiner) {
        return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6,
            Publisher p7,
            Function7 combiner) {
        return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6,
            Publisher p7, Publisher p8,
            Function8 combiner) {
        return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable combineLatest(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6,
            Publisher p7, Publisher p8,
            Publisher p9,
            Function9 combiner) {
        return combineLatest(Functions.toFunction(combiner), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(int prefetch, Iterable> sources) {
        Objects.requireNonNull(sources, "sources is null");
        return fromIterable(sources).concatMap((Function)Functions.identity(), prefetch);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(Iterable> sources) {
        Objects.requireNonNull(sources, "sources is null");
        return fromIterable(sources).concatMap((Function)Functions.identity());
    }

    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static final  Observable concat(Publisher> sources) {
        return concat(sources, bufferSize());
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static final  Observable concat(Publisher> sources, int bufferSize) {
        return fromPublisher(sources).concatMap((Function)Functions.identity());
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(Publisher p1, Publisher p2) {
        return concatArray(p1, p2);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(
            Publisher p1, Publisher p2,
            Publisher p3) {
        return concatArray(p1, p2, p3);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(
            Publisher p1, Publisher p2,
            Publisher p3, Publisher p4) {
        return concatArray(p1, p2, p3, p4);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5
    ) {
        return concatArray(p1, p2, p3, p4, p5);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6
    ) {
        return concatArray(p1, p2, p3, p4, p5, p6);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(
            Publisher p1, Publisher p2,
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6,
            Publisher p7
    ) {
        return concatArray(p1, p2, p3, p4, p5, p6, p7);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6,
            Publisher p7, Publisher p8
    ) {
        return concatArray(p1, p2, p3, p4, p5, p6, p7, p8);
    }

    @SuppressWarnings("unchecked")
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concat(
            Publisher p1, Publisher p2, 
            Publisher p3, Publisher p4,
            Publisher p5, Publisher p6,
            Publisher p7, Publisher p8,
            Publisher p9
    ) {
        return concatArray(p1, p2, p3, p4, p5, p6, p7, p8, p9);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerKind.NONE)
    public static  Observable concatArray(int prefetch, Publisher... sources) {
        Objects.requireNonNull(sources, "sources is null");
        return fromArray(sources).concatMap((Function)Functions.identity(), prefetch);
    }

    /**
     * Concatenates a variable number of Observable sources.
     * 

* Note: named this way because of overload conflict with concat(NbpObservable<NbpObservable>) * @param sources the array of sources * @param the common base value type * @return the new NbpObservable instance * @throws NullPointerException if sources is null */ @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable concatArray(Publisher... sources) { if (sources.length == 0) { return empty(); } else if (sources.length == 1) { return fromPublisher(sources[0]); } return fromArray(sources).concatMap((Function)Functions.identity()); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public static Observable create(Publisher onSubscribe) { Objects.requireNonNull(onSubscribe, "onSubscribe is null"); onSubscribe = RxJavaPlugins.onCreate(onSubscribe); return new Observable(onSubscribe); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable defer(Supplier> supplier) { Objects.requireNonNull(supplier, "supplier is null"); return create(new PublisherDefer(supplier)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings("unchecked") public static Observable empty() { return (Observable)EMPTY; } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable error(Supplier errorSupplier) { Objects.requireNonNull(errorSupplier, "errorSupplier is null"); return create(new PublisherErrorSource(errorSupplier)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable error(final Throwable e) { Objects.requireNonNull(e, "e is null"); return error(new Supplier() { @Override public Throwable get() { return e; } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromArray(T... values) { Objects.requireNonNull(values, "values is null"); if (values.length == 0) { return empty(); } else if (values.length == 1) { return just(values[0]); } return create(new PublisherArraySource(values)); } // TODO match naming with RxJava 1.x @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromCallable(Callable supplier) { Objects.requireNonNull(supplier, "supplier is null"); return create(new PublisherScalarAsyncSource(supplier)); } /* * It doesn't add cancellation support by default like 1.x * if necessary, one can use composition to achieve it: * futureObservable.doOnCancel(() -> future.cancel(true)); */ @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromFuture(Future future) { Objects.requireNonNull(future, "future is null"); Observable o = create(new PublisherFutureSource(future, 0L, null)); return o; } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromFuture(Future future, long timeout, TimeUnit unit) { Objects.requireNonNull(future, "future is null"); Objects.requireNonNull(unit, "unit is null"); Observable o = create(new PublisherFutureSource(future, timeout, unit)); return o; } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public static Observable fromFuture(Future future, long timeout, TimeUnit unit, Scheduler scheduler) { Objects.requireNonNull(scheduler, "scheduler is null"); Observable o = fromFuture(future, timeout, unit); return o.subscribeOn(scheduler); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.IO) public static Observable fromFuture(Future future, Scheduler scheduler) { Objects.requireNonNull(scheduler, "scheduler is null"); Observable o = fromFuture(future); return o.subscribeOn(Schedulers.io()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable fromIterable(Iterable source) { Objects.requireNonNull(source, "source is null"); return create(new PublisherIterableSource(source)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings("unchecked") public static Observable fromPublisher(final Publisher publisher) { if (publisher instanceof Observable) { return (Observable)publisher; } Objects.requireNonNull(publisher, "publisher is null"); return create(new Publisher() { @Override public void subscribe(Subscriber s) { publisher.subscribe(s); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable generate(final Consumer> generator) { Objects.requireNonNull(generator, "generator is null"); return generate(Functions.nullSupplier(), new BiFunction, Object>() { @Override public Object apply(Object s, Subscriber o) { generator.accept(o); return s; } }, Functions.emptyConsumer()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable generate(Supplier initialState, final BiConsumer> generator) { Objects.requireNonNull(generator, "generator is null"); return generate(initialState, new BiFunction, S>() { @Override public S apply(S s, Subscriber o) { generator.accept(s, o); return s; } }, Functions.emptyConsumer()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable generate(Supplier initialState, final BiConsumer> generator, Consumer disposeState) { Objects.requireNonNull(generator, "generator is null"); return generate(initialState, new BiFunction, S>() { @Override public S apply(S s, Subscriber o) { generator.accept(s, o); return s; } }, disposeState); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable generate(Supplier initialState, BiFunction, S> generator) { return generate(initialState, generator, Functions.emptyConsumer()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable generate(Supplier initialState, BiFunction, S> generator, Consumer disposeState) { Objects.requireNonNull(initialState, "initialState is null"); Objects.requireNonNull(generator, "generator is null"); Objects.requireNonNull(disposeState, "disposeState is null"); return create(new PublisherGenerate(initialState, generator, disposeState)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public static Observable interval(long initialDelay, long period, TimeUnit unit) { return interval(initialDelay, period, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public static Observable interval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler) { if (initialDelay < 0) { initialDelay = 0L; } if (period < 0) { period = 0L; } Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return create(new PublisherIntervalSource(initialDelay, period, unit, scheduler)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public static Observable interval(long period, TimeUnit unit) { return interval(period, period, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public static Observable interval(long period, TimeUnit unit, Scheduler scheduler) { return interval(period, period, unit, scheduler); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public static Observable intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit) { return intervalRange(start, count, initialDelay, period, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public static Observable intervalRange(long start, long count, long initialDelay, long period, TimeUnit unit, Scheduler scheduler) { long end = start + (count - 1); if (end < 0) { throw new IllegalArgumentException("Overflow! start + count is bigger than Long.MAX_VALUE"); } if (initialDelay < 0) { initialDelay = 0L; } if (period < 0) { period = 0L; } Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return create(new PublisherIntervalRangeSource(start, end, initialDelay, period, unit, scheduler)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable just(T value) { Objects.requireNonNull(value, "value is null"); return new ObservableScalarSource(value); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); return fromArray(v1, v2); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); Objects.requireNonNull(v3, "The third value is null"); return fromArray(v1, v2, v3); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); return fromArray(v1, v2, v3, v4); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); Objects.requireNonNull(v5, "The fifth value is null"); return fromArray(v1, v2, v3, v4, v5); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); Objects.requireNonNull(v5, "The fifth value is null"); Objects.requireNonNull(v6, "The sixth value is null"); return fromArray(v1, v2, v3, v4, v5, v6); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); Objects.requireNonNull(v5, "The fifth value is null"); Objects.requireNonNull(v6, "The sixth value is null"); Objects.requireNonNull(v7, "The seventh value is null"); return fromArray(v1, v2, v3, v4, v5, v6, v7); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); Objects.requireNonNull(v5, "The fifth value is null"); Objects.requireNonNull(v6, "The sixth value is null"); Objects.requireNonNull(v7, "The seventh value is null"); Objects.requireNonNull(v8, "The eigth value is null"); return fromArray(v1, v2, v3, v4, v5, v6, v7, v8); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static final Observable just(T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8, T v9) { Objects.requireNonNull(v1, "The first value is null"); Objects.requireNonNull(v2, "The second value is null"); Objects.requireNonNull(v3, "The third value is null"); Objects.requireNonNull(v4, "The fourth value is null"); Objects.requireNonNull(v5, "The fifth value is null"); Objects.requireNonNull(v6, "The sixth value is null"); Objects.requireNonNull(v7, "The seventh value is null"); Objects.requireNonNull(v8, "The eigth value is null"); Objects.requireNonNull(v9, "The ninth is null"); return fromArray(v1, v2, v3, v4, v5, v6, v7, v8, v9); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(int maxConcurrency, int bufferSize, Iterable> sources) { return fromIterable(sources).flatMap((Function)Functions.identity(), false, maxConcurrency, bufferSize); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(int maxConcurrency, int bufferSize, Publisher... sources) { return fromArray(sources).flatMap((Function)Functions.identity(), false, maxConcurrency, bufferSize); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(int maxConcurrency, Publisher... sources) { return fromArray(sources).flatMap((Function)Functions.identity(), maxConcurrency); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Iterable> sources) { return fromIterable(sources).flatMap((Function)Functions.identity()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Iterable> sources, int maxConcurrency) { return fromIterable(sources).flatMap((Function)Functions.identity(), maxConcurrency); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Publisher> sources) { return merge(sources, bufferSize()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Publisher> sources, int maxConcurrency) { return fromPublisher(sources).flatMap((Function)Functions.identity(), maxConcurrency); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Publisher... sources) { return fromArray(sources).flatMap((Function)Functions.identity(), sources.length); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Publisher p1, Publisher p2) { Objects.requireNonNull(p1, "p1 is null"); Objects.requireNonNull(p2, "p2 is null"); return fromArray(p1, p2).flatMap((Function)Functions.identity(), false, 2); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge(Publisher p1, Publisher p2, Publisher p3) { Objects.requireNonNull(p1, "p1 is null"); Objects.requireNonNull(p2, "p2 is null"); Objects.requireNonNull(p3, "p3 is null"); return fromArray(p1, p2, p3).flatMap((Function)Functions.identity(), false, 3); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable merge( Publisher p1, Publisher p2, Publisher p3, Publisher p4) { Objects.requireNonNull(p1, "p1 is null"); Objects.requireNonNull(p2, "p2 is null"); Objects.requireNonNull(p3, "p3 is null"); Objects.requireNonNull(p4, "p4 is null"); return fromArray(p1, p2, p3, p4).flatMap((Function)Functions.identity(), false, 4); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(boolean delayErrors, Iterable> sources) { return fromIterable(sources).flatMap((Function)Functions.identity(), true); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(int maxConcurrency, int bufferSize, Iterable> sources) { return fromIterable(sources).flatMap((Function)Functions.identity(), true, maxConcurrency, bufferSize); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(int maxConcurrency, int bufferSize, Publisher... sources) { return fromArray(sources).flatMap((Function)Functions.identity(), true, maxConcurrency, bufferSize); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(int maxConcurrency, Iterable> sources) { return fromIterable(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(int maxConcurrency, Publisher... sources) { return fromArray(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(Publisher> sources) { return mergeDelayError(sources, bufferSize()); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(Publisher> sources, int maxConcurrency) { return fromPublisher(sources).flatMap((Function)Functions.identity(), true, maxConcurrency); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(Publisher... sources) { return fromArray(sources).flatMap((Function)Functions.identity(), true, sources.length); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(Publisher p1, Publisher p2) { Objects.requireNonNull(p1, "p1 is null"); Objects.requireNonNull(p2, "p2 is null"); return fromArray(p1, p2).flatMap((Function)Functions.identity(), true, 2); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError(Publisher p1, Publisher p2, Publisher p3) { Objects.requireNonNull(p1, "p1 is null"); Objects.requireNonNull(p2, "p2 is null"); Objects.requireNonNull(p3, "p3 is null"); return fromArray(p1, p2, p3).flatMap((Function)Functions.identity(), true, 3); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable mergeDelayError( Publisher p1, Publisher p2, Publisher p3, Publisher p4) { Objects.requireNonNull(p1, "p1 is null"); Objects.requireNonNull(p2, "p2 is null"); Objects.requireNonNull(p3, "p3 is null"); Objects.requireNonNull(p4, "p4 is null"); return fromArray(p1, p2, p3, p4).flatMap((Function)Functions.identity(), true, 4); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings("unchecked") public static Observable never() { return (Observable)NEVER; } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable range(int start, int count) { if (count < 0) { throw new IllegalArgumentException("count >= required but it was " + count); } else if (count == 0) { return empty(); } else if (count == 1) { return just(start); } else if ((long)start + (count - 1) > Integer.MAX_VALUE) { throw new IllegalArgumentException("Integer overflow"); } return create(new PublisherRangeSource(start, count)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable sequenceEqual(Publisher p1, Publisher p2) { return sequenceEqual(p1, p2, Objects.equalsPredicate(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable sequenceEqual(Publisher p1, Publisher p2, BiPredicate isEqual) { return sequenceEqual(p1, p2, isEqual, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable sequenceEqual(Publisher p1, Publisher p2, BiPredicate isEqual, int bufferSize) { Objects.requireNonNull(p1, "p1 is null"); Objects.requireNonNull(p2, "p2 is null"); Objects.requireNonNull(isEqual, "isEqual is null"); validateBufferSize(bufferSize); return create(new PublisherSequenceEqual(p1, p2, isEqual, bufferSize)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable sequenceEqual(Publisher p1, Publisher p2, int bufferSize) { return sequenceEqual(p1, p2, Objects.equalsPredicate(), bufferSize); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable switchOnNext(int bufferSize, Publisher> sources) { return fromPublisher(sources).switchMap((Function)Functions.identity(), bufferSize); } @SuppressWarnings({ "unchecked", "rawtypes" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable switchOnNext(Publisher> sources) { return fromPublisher(sources).switchMap((Function)Functions.identity()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public static Observable timer(long delay, TimeUnit unit) { return timer(delay, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public static Observable timer(long delay, TimeUnit unit, Scheduler scheduler) { if (delay < 0) { delay = 0L; } Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return create(new PublisherIntervalOnceSource(delay, unit, scheduler)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable using(Supplier resourceSupplier, Function> sourceSupplier, Consumer disposer) { return using(resourceSupplier, sourceSupplier, disposer, true); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public static Observable using(Supplier resourceSupplier, Function> sourceSupplier, Consumer disposer, boolean eager) { Objects.requireNonNull(resourceSupplier, "resourceSupplier is null"); Objects.requireNonNull(sourceSupplier, "sourceSupplier is null"); Objects.requireNonNull(disposer, "disposer is null"); return create(new PublisherUsing(resourceSupplier, sourceSupplier, disposer, eager)); } private static void validateBufferSize(int bufferSize) { if (bufferSize <= 0) { throw new IllegalArgumentException("bufferSize > 0 required but it was " + bufferSize); } } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip(Iterable> sources, Function zipper) { Objects.requireNonNull(zipper, "zipper is null"); Objects.requireNonNull(sources, "sources is null"); return create(new PublisherZip(null, sources, zipper, bufferSize(), false)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip(Publisher> sources, final Function zipper) { Objects.requireNonNull(zipper, "zipper is null"); return fromPublisher(sources).toList().flatMap(new Function>, Publisher>() { @Override public Publisher apply(List> list) { return zipIterable(zipper, false, bufferSize(), list); } }); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, BiFunction zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, BiFunction zipper, boolean delayError) { return zipArray(Functions.toFunction(zipper), delayError, bufferSize(), p1, p2); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, BiFunction zipper, boolean delayError, int bufferSize) { return zipArray(Functions.toFunction(zipper), delayError, bufferSize, p1, p2); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Function3 zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Function4 zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Publisher p5, Function5 zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Publisher p5, Publisher p6, Function6 zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Publisher p5, Publisher p6, Publisher p7, Function7 zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Publisher p5, Publisher p6, Publisher p7, Publisher p8, Function8 zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zip( Publisher p1, Publisher p2, Publisher p3, Publisher p4, Publisher p5, Publisher p6, Publisher p7, Publisher p8, Publisher p9, Function9 zipper) { return zipArray(Functions.toFunction(zipper), false, bufferSize(), p1, p2, p3, p4, p5, p6, p7, p8, p9); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zipArray(Function zipper, boolean delayError, int bufferSize, Publisher... sources) { if (sources.length == 0) { return empty(); } Objects.requireNonNull(zipper, "zipper is null"); validateBufferSize(bufferSize); return create(new PublisherZip(sources, null, zipper, bufferSize, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public static Observable zipIterable(Function zipper, boolean delayError, int bufferSize, Iterable> sources) { Objects.requireNonNull(zipper, "zipper is null"); Objects.requireNonNull(sources, "sources is null"); validateBufferSize(bufferSize); return create(new PublisherZip(null, sources, zipper, bufferSize, delayError)); } final Publisher onSubscribe; protected Observable(Publisher onSubscribe) { this.onSubscribe = onSubscribe; } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable all(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return lift(new OperatorAll(predicate)); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable ambWith(Publisher other) { Objects.requireNonNull(other, "other is null"); return amb(this, other); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable any(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return lift(new OperatorAny(predicate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable asObservable() { return create(new Publisher() { @Override public void subscribe(Subscriber s) { Observable.this.subscribe(s); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> buffer(int count) { return buffer(count, count); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> buffer(int count, int skip) { return buffer(count, skip, new Supplier>() { @Override public List get() { return new ArrayList(); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final > Observable buffer(int count, int skip, Supplier bufferSupplier) { Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); return lift(new OperatorBuffer(count, skip, bufferSupplier)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final > Observable buffer(int count, Supplier bufferSupplier) { return buffer(count, count, bufferSupplier); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> buffer(long timespan, long timeskip, TimeUnit unit) { return buffer(timespan, timeskip, unit, Schedulers.computation(), new Supplier>() { @Override public List get() { return new ArrayList(); } }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> buffer(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler) { return buffer(timespan, timeskip, unit, scheduler, new Supplier>() { @Override public List get() { return new ArrayList(); } }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final > Observable buffer(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler, Supplier bufferSupplier) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); return lift(new OperatorBufferTimed(timespan, timeskip, unit, scheduler, bufferSupplier, Integer.MAX_VALUE, false)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> buffer(long timespan, TimeUnit unit) { return buffer(timespan, unit, Integer.MAX_VALUE, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> buffer(long timespan, TimeUnit unit, int count) { return buffer(timespan, unit, count, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> buffer(long timespan, TimeUnit unit, int count, Scheduler scheduler) { return buffer(timespan, unit, count, scheduler, new Supplier>() { @Override public List get() { return new ArrayList(); } }, false); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final > Observable buffer( long timespan, TimeUnit unit, int count, Scheduler scheduler, Supplier bufferSupplier, boolean restartTimerOnMaxSize) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } return lift(new OperatorBufferTimed(timespan, timespan, unit, scheduler, bufferSupplier, count, restartTimerOnMaxSize)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> buffer(long timespan, TimeUnit unit, Scheduler scheduler) { return buffer(timespan, unit, Integer.MAX_VALUE, scheduler, new Supplier>() { @Override public List get() { return new ArrayList(); } }, false); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> buffer( Observable bufferOpenings, Function> bufferClosingSelector) { return buffer(bufferOpenings, bufferClosingSelector, new Supplier>() { @Override public List get() { return new ArrayList(); } }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final > Observable buffer( Observable bufferOpenings, Function> bufferClosingSelector, Supplier bufferSupplier) { Objects.requireNonNull(bufferOpenings, "bufferOpenings is null"); Objects.requireNonNull(bufferClosingSelector, "bufferClosingSelector is null"); Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); return lift(new OperatorBufferBoundary(bufferOpenings, bufferClosingSelector, bufferSupplier)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> buffer(Publisher boundary) { /* * XXX: javac complains if this is not manually cast, Eclipse is fine */ return buffer(boundary, new Supplier>() { @Override public List get() { return new ArrayList(); } }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> buffer(Publisher boundary, final int initialCapacity) { return buffer(boundary, new Supplier>() { @Override public List get() { return new ArrayList(initialCapacity); } }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final > Observable buffer(Publisher boundary, Supplier bufferSupplier) { Objects.requireNonNull(boundary, "boundary is null"); Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); return lift(new OperatorBufferExactBoundary(boundary, bufferSupplier)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> buffer(Supplier> boundarySupplier) { return buffer(boundarySupplier, new Supplier>() { @Override public List get() { return new ArrayList(); } }); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final > Observable buffer(Supplier> boundarySupplier, Supplier bufferSupplier) { Objects.requireNonNull(boundarySupplier, "boundarySupplier is null"); Objects.requireNonNull(bufferSupplier, "bufferSupplier is null"); return lift(new OperatorBufferBoundarySupplier(boundarySupplier, bufferSupplier)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable cache() { return CachedObservable.from(this); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable cache(int capacityHint) { if (capacityHint <= 0) { throw new IllegalArgumentException("capacityHint > 0 required but it was " + capacityHint); } return CachedObservable.from(this, capacityHint); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable cast(final Class clazz) { Objects.requireNonNull(clazz, "clazz is null"); return map(new Function() { @Override public U apply(T v) { return clazz.cast(v); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable collect(Supplier initialValueSupplier, BiConsumer collector) { Objects.requireNonNull(initialValueSupplier, "initialValueSupplier is null"); Objects.requireNonNull(collector, "collectior is null"); return lift(new OperatorCollect(initialValueSupplier, collector)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable collectInto(final U initialValue, BiConsumer collector) { Objects.requireNonNull(initialValue, "initialValue is null"); return collect(new Supplier() { @Override public U get() { return initialValue; } }, collector); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) // TODO generics public final Observable compose(Transformer composer) { return fromPublisher(to(composer)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable concatMap(Function> mapper) { return concatMap(mapper, 2); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable concatMap(Function> mapper, int prefetch) { Objects.requireNonNull(mapper, "mapper is null"); if (prefetch <= 0) { throw new IllegalArgumentException("prefetch > 0 required but it was " + prefetch); } return lift(new OperatorConcatMap(mapper, prefetch)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable concatMapIterable(Function> mapper) { return concatMapIterable(mapper, 2); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable concatMapIterable(final Function> mapper, int prefetch) { Objects.requireNonNull(mapper, "mapper is null"); return concatMap(new Function>() { @Override public Publisher apply(T v) { return new PublisherIterableSource(mapper.apply(v)); } }, prefetch); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable concatWith(Publisher other) { Objects.requireNonNull(other, "other is null"); return concat(this, other); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable contains(final Object o) { Objects.requireNonNull(o, "o is null"); return any(new Predicate() { @Override public boolean test(T v) { return Objects.equals(v, o); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable count() { return lift(OperatorCount.instance()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable debounce(Function> debounceSelector) { Objects.requireNonNull(debounceSelector, "debounceSelector is null"); return lift(new OperatorDebounce(debounceSelector)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable debounce(long timeout, TimeUnit unit) { return debounce(timeout, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable debounce(long timeout, TimeUnit unit, Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorDebounceTimed(timeout, unit, scheduler)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable defaultIfEmpty(T value) { Objects.requireNonNull(value, "value is null"); return switchIfEmpty(just(value)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) // TODO a more efficient implementation if necessary public final Observable delay(final Function> itemDelay) { Objects.requireNonNull(itemDelay, "itemDelay is null"); return flatMap(new Function>() { @Override public Publisher apply(final T v) { return fromPublisher(itemDelay.apply(v)).take(1).map(new Function() { @Override public T apply(U u) { return v; } }).defaultIfEmpty(v); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable delay(long delay, TimeUnit unit) { return delay(delay, unit, Schedulers.computation(), false); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable delay(long delay, TimeUnit unit, boolean delayError) { return delay(delay, unit, Schedulers.computation(), delayError); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable delay(long delay, TimeUnit unit, Scheduler scheduler) { return delay(delay, unit, scheduler, false); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable delay(long delay, TimeUnit unit, Scheduler scheduler, boolean delayError) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorDelay(delay, unit, scheduler, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable delay(Supplier> delaySupplier, Function> itemDelay) { return delaySubscription(delaySupplier).delay(itemDelay); } /** * Returns an Observable that delays the subscription to this Observable * until the other Observable emits an element or completes normally. *

*

*
Backpressure:
*
The operator forwards the backpressure requests to this Observable once * the subscription happens and requests Long.MAX_VALUE from the other Observable
*
Scheduler:
*
This method does not operate by default on a particular {@link Scheduler}.
*
* * @param the value type of the other Observable, irrelevant * @param other the other Observable that should trigger the subscription * to this Observable. * @return an Observable that delays the subscription to this Observable * until the other Observable emits an element or completes normally. */ @Experimental public final Observable delaySubscription(Publisher other) { Objects.requireNonNull(other, "other is null"); return create(new PublisherDelaySubscriptionOther(this, other)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable delaySubscription(long delay, TimeUnit unit) { return delaySubscription(delay, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) // TODO a more efficient implementation if necessary public final Observable delaySubscription(long delay, TimeUnit unit, Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return timer(delay, unit, scheduler).flatMap(new Function>() { @Override public Publisher apply(Long v) { return Observable.this; } }); } private static final Object OBJECT = new Object(); @SuppressWarnings({ "rawtypes", "unchecked" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable delaySubscription(final Supplier> delaySupplier) { Objects.requireNonNull(delaySupplier, "delaySupplier is null"); return fromCallable(new Callable() { @Override public Object call() throws Exception { return delaySupplier.get(); } }) .flatMap((Function)Functions.identity()) .take(1) .cast(Object.class) // need a common supertype, the value is not relevant .defaultIfEmpty(OBJECT) // in case the publisher is empty .flatMap(new Function() { @Override public Object apply(Object v) { return Observable.this; } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable dematerialize() { @SuppressWarnings("unchecked") Observable>> m = (Observable>>)this; return m.lift(OperatorDematerialize.instance()); } @SuppressWarnings({ "rawtypes", "unchecked" }) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinct() { return distinct((Function)Functions.identity(), new Supplier>() { @Override public Collection get() { return new HashSet(); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinct(Function keySelector) { return distinct(keySelector, new Supplier>() { @Override public Collection get() { return new HashSet(); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinct(Function keySelector, Supplier> collectionSupplier) { Objects.requireNonNull(keySelector, "keySelector is null"); Objects.requireNonNull(collectionSupplier, "collectionSupplier is null"); return lift(OperatorDistinct.withCollection(keySelector, collectionSupplier)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinctUntilChanged() { return lift(OperatorDistinct.untilChanged()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable distinctUntilChanged(Function keySelector) { Objects.requireNonNull(keySelector, "keySelector is null"); return lift(OperatorDistinct.untilChanged(keySelector)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnCancel(Runnable onCancel) { return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyLongConsumer(), onCancel); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnComplete(Runnable onComplete) { return doOnEach(Functions.emptyConsumer(), Functions.emptyConsumer(), onComplete, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) private Observable doOnEach(Consumer onNext, Consumer onError, Runnable onComplete, Runnable onAfterTerminate) { Objects.requireNonNull(onNext, "onNext is null"); Objects.requireNonNull(onError, "onError is null"); Objects.requireNonNull(onComplete, "onComplete is null"); Objects.requireNonNull(onAfterTerminate, "onAfterTerminate is null"); return lift(new OperatorDoOnEach(onNext, onError, onComplete, onAfterTerminate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnEach(final Consumer>> consumer) { Objects.requireNonNull(consumer, "consumer is null"); return doOnEach( new Consumer() { @Override public void accept(T v) { consumer.accept(Try.ofValue(Optional.of(v))); } }, new Consumer() { @Override public void accept(Throwable e) { consumer.accept(Try.>ofError(e)); } }, new Runnable() { @Override public void run() { consumer.accept(Try.ofValue(Optional.empty())); } }, Functions.emptyRunnable() ); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnEach(final Subscriber observer) { Objects.requireNonNull(observer, "observer is null"); return doOnEach(new Consumer() { @Override public void accept(T v) { observer.onNext(v); } }, new Consumer() { @Override public void accept(Throwable e) { observer.onError(e); } }, new Runnable() { @Override public void run() { observer.onComplete(); } }, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnError(Consumer onError) { return doOnEach(Functions.emptyConsumer(), onError, Functions.emptyRunnable(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnLifecycle(final Consumer onSubscribe, final LongConsumer onRequest, final Runnable onCancel) { Objects.requireNonNull(onSubscribe, "onSubscribe is null"); Objects.requireNonNull(onRequest, "onRequest is null"); Objects.requireNonNull(onCancel, "onCancel is null"); return lift(new Operator() { @Override public Subscriber apply(Subscriber s) { return new SubscriptionLambdaSubscriber(s, onSubscribe, onRequest, onCancel); } }); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnNext(Consumer onNext) { return doOnEach(onNext, Functions.emptyConsumer(), Functions.emptyRunnable(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnRequest(LongConsumer onRequest) { return doOnLifecycle(Functions.emptyConsumer(), onRequest, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnSubscribe(Consumer onSubscribe) { return doOnLifecycle(onSubscribe, Functions.emptyLongConsumer(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable doOnTerminate(final Runnable onTerminate) { return doOnEach(Functions.emptyConsumer(), new Consumer() { @Override public void accept(Throwable e) { onTerminate.run(); } }, onTerminate, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable elementAt(long index) { if (index < 0) { throw new IndexOutOfBoundsException("index >= 0 required but it was " + index); } return lift(new OperatorElementAt(index, null)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable elementAt(long index, T defaultValue) { if (index < 0) { throw new IndexOutOfBoundsException("index >= 0 required but it was " + index); } Objects.requireNonNull(defaultValue, "defaultValue is null"); return lift(new OperatorElementAt(index, defaultValue)); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable endWith(Iterable values) { return concatArray(this, fromIterable(values)); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable endWith(Publisher other) { Objects.requireNonNull(other, "other is null"); return concatArray(this, other); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable endWith(T value) { Objects.requireNonNull(value, "value is null"); return concatArray(this, just(value)); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable endWithArray(T... values) { Observable fromArray = fromArray(values); if (fromArray == empty()) { return this; } return concatArray(this, fromArray); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable filter(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return lift(new OperatorFilter(predicate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable finallyDo(Runnable onFinally) { return doOnEach(Functions.emptyConsumer(), Functions.emptyConsumer(), Functions.emptyRunnable(), onFinally); } @BackpressureSupport(BackpressureKind.SPECIAL) // take may trigger UNBOUNDED_IN @SchedulerSupport(SchedulerKind.NONE) public final Observable first() { return take(1).single(); } @BackpressureSupport(BackpressureKind.SPECIAL) // take may trigger UNBOUNDED_IN @SchedulerSupport(SchedulerKind.NONE) public final Observable first(T defaultValue) { return take(1).single(defaultValue); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper) { return flatMap(mapper, false, bufferSize(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, boolean delayErrors) { return flatMap(mapper, delayErrors, bufferSize(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, boolean delayErrors, int maxConcurrency) { return flatMap(mapper, delayErrors, maxConcurrency, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, boolean delayErrors, int maxConcurrency, int bufferSize) { Objects.requireNonNull(mapper, "mapper is null"); if (maxConcurrency <= 0) { throw new IllegalArgumentException("maxConcurrency > 0 required but it was " + maxConcurrency); } validateBufferSize(bufferSize); if (this instanceof ObservableScalarSource) { ObservableScalarSource scalar = (ObservableScalarSource) this; return create(scalar.scalarFlatMap(mapper)); } return lift(new OperatorFlatMap(mapper, delayErrors, maxConcurrency, bufferSize)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap( Function> onNextMapper, Function> onErrorMapper, Supplier> onCompleteSupplier) { Objects.requireNonNull(onNextMapper, "onNextMapper is null"); Objects.requireNonNull(onErrorMapper, "onErrorMapper is null"); Objects.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null"); return merge(lift(new OperatorMapNotification(onNextMapper, onErrorMapper, onCompleteSupplier))); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap( Function> onNextMapper, Function> onErrorMapper, Supplier> onCompleteSupplier, int maxConcurrency) { Objects.requireNonNull(onNextMapper, "onNextMapper is null"); Objects.requireNonNull(onErrorMapper, "onErrorMapper is null"); Objects.requireNonNull(onCompleteSupplier, "onCompleteSupplier is null"); return merge(lift(new OperatorMapNotification(onNextMapper, onErrorMapper, onCompleteSupplier)), maxConcurrency); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, int maxConcurrency) { return flatMap(mapper, false, maxConcurrency, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, BiFunction resultSelector) { return flatMap(mapper, resultSelector, false, bufferSize(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, BiFunction combiner, boolean delayError) { return flatMap(mapper, combiner, delayError, bufferSize(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, BiFunction combiner, boolean delayError, int maxConcurrency) { return flatMap(mapper, combiner, delayError, maxConcurrency, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(final Function> mapper, final BiFunction combiner, boolean delayError, int maxConcurrency, int bufferSize) { Objects.requireNonNull(mapper, "mapper is null"); Objects.requireNonNull(combiner, "combiner is null"); return flatMap(new Function>() { @Override public Publisher apply(final T t) { Observable u = fromPublisher(mapper.apply(t)); return u.map(new Function() { @Override public R apply(U w) { return combiner.apply(t, w); } }); } }, delayError, maxConcurrency, bufferSize); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMap(Function> mapper, BiFunction combiner, int maxConcurrency) { return flatMap(mapper, combiner, false, maxConcurrency, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMapIterable(final Function> mapper) { Objects.requireNonNull(mapper, "mapper is null"); return flatMap(new Function>() { @Override public Publisher apply(T v) { return new PublisherIterableSource(mapper.apply(v)); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMapIterable(final Function> mapper, final BiFunction resultSelector) { Objects.requireNonNull(mapper, "mapper is null"); Objects.requireNonNull(resultSelector, "resultSelector is null"); return flatMap(new Function>() { @Override public Publisher apply(T t) { return new PublisherIterableSource(mapper.apply(t)); } }, resultSelector, false, bufferSize(), bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable flatMapIterable(final Function> mapper, int bufferSize) { return flatMap(new Function>() { @Override public Publisher apply(T v) { return new PublisherIterableSource(mapper.apply(v)); } }, false, bufferSize); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEach(Consumer onNext) { return subscribe(onNext); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEachWhile(Predicate onNext) { return forEachWhile(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEachWhile(Predicate onNext, Consumer onError) { return forEachWhile(onNext, onError, Functions.emptyRunnable()); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public final Disposable forEachWhile(final Predicate onNext, final Consumer onError, final Runnable onComplete) { Objects.requireNonNull(onNext, "onNext is null"); Objects.requireNonNull(onError, "onError is null"); Objects.requireNonNull(onComplete, "onComplete is null"); final AtomicReference subscription = new AtomicReference(); return subscribe(new Consumer() { @Override public void accept(T v) { if (!onNext.test(v)) { subscription.get().cancel(); onComplete.run(); } } }, onError, onComplete, new Consumer() { @Override public void accept(Subscription s) { subscription.lazySet(s); s.request(Long.MAX_VALUE); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> groupBy(Function keySelector) { return groupBy(keySelector, Functions.identity(), false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> groupBy(Function keySelector, boolean delayError) { return groupBy(keySelector, Functions.identity(), delayError, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> groupBy(Function keySelector, Function valueSelector) { return groupBy(keySelector, valueSelector, false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> groupBy(Function keySelector, Function valueSelector, boolean delayError) { return groupBy(keySelector, valueSelector, false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> groupBy(Function keySelector, Function valueSelector, boolean delayError, int bufferSize) { Objects.requireNonNull(keySelector, "keySelector is null"); Objects.requireNonNull(valueSelector, "valueSelector is null"); validateBufferSize(bufferSize); return lift(new OperatorGroupBy(keySelector, valueSelector, bufferSize, delayError)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable ignoreElements() { return lift(OperatorIgnoreElements.instance()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable isEmpty() { return all(new Predicate() { @Override public boolean test(T v) { return false; } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable last() { return takeLast(1).single(); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable last(T defaultValue) { return takeLast(1).single(defaultValue); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final Observable lift(Operator lifter) { Objects.requireNonNull(lifter, "lifter is null"); // using onSubscribe so the fusing has access to the underlying raw Publisher return create(new PublisherLift(onSubscribe, lifter)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable map(Function mapper) { Objects.requireNonNull(mapper, "mapper is null"); return lift(new OperatorMap(mapper)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable>> materialize() { return lift(OperatorMaterialize.instance()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable mergeWith(Publisher other) { Objects.requireNonNull(other, "other is null"); return merge(this, other); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) @Deprecated public final Observable> nest() { return just(this); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable observeOn(Scheduler scheduler) { return observeOn(scheduler, false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable observeOn(Scheduler scheduler, boolean delayError) { return observeOn(scheduler, delayError, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) { Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); return lift(new OperatorObserveOn(scheduler, delayError, bufferSize)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable ofType(final Class clazz) { Objects.requireNonNull(clazz, "clazz is null"); return filter(new Predicate() { @Override public boolean test(T c) { return clazz.isInstance(c); } }).cast(clazz); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer() { return onBackpressureBuffer(bufferSize(), false, true); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(boolean delayError) { return onBackpressureBuffer(bufferSize(), true, true); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(int bufferSize) { return onBackpressureBuffer(bufferSize, false, false); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(int bufferSize, boolean delayError) { return onBackpressureBuffer(bufferSize, true, false); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(int bufferSize, boolean delayError, boolean unbounded) { validateBufferSize(bufferSize); return lift(new OperatorOnBackpressureBuffer(bufferSize, unbounded, delayError, Functions.emptyRunnable())); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(int bufferSize, boolean delayError, boolean unbounded, Runnable onOverflow) { Objects.requireNonNull(onOverflow, "onOverflow is null"); return lift(new OperatorOnBackpressureBuffer(bufferSize, unbounded, delayError, onOverflow)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureBuffer(int bufferSize, Runnable onOverflow) { return onBackpressureBuffer(bufferSize, false, false, onOverflow); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureDrop() { return lift(OperatorOnBackpressureDrop.instance()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureDrop(Consumer onDrop) { Objects.requireNonNull(onDrop, "onDrop is null"); return lift(new OperatorOnBackpressureDrop(onDrop)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable onBackpressureLatest() { return lift(OperatorOnBackpressureLatest.instance()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onErrorResumeNext(Function> resumeFunction) { Objects.requireNonNull(resumeFunction, "resumeFunction is null"); return lift(new OperatorOnErrorNext(resumeFunction, false)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onErrorResumeNext(final Publisher next) { Objects.requireNonNull(next, "next is null"); return onErrorResumeNext(new Function>() { @Override public Publisher apply(Throwable e) { return next; } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onErrorReturn(Function valueSupplier) { Objects.requireNonNull(valueSupplier, "valueSupplier is null"); return lift(new OperatorOnErrorReturn(valueSupplier)); } // TODO would result in ambiguity with onErrorReturn(Function) @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onErrorReturnValue(final T value) { Objects.requireNonNull(value, "value is null"); return onErrorReturn(new Function() { @Override public T apply(Throwable e) { return value; } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable onExceptionResumeNext(final Publisher next) { Objects.requireNonNull(next, "next is null"); return lift(new OperatorOnErrorNext(new Function>() { @Override public Publisher apply(Throwable e) { return next; } }, true)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final ConnectableObservable publish() { return publish(bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable publish(Function, ? extends Publisher> selector) { return publish(selector, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable publish(Function, ? extends Publisher> selector, int bufferSize) { validateBufferSize(bufferSize); Objects.requireNonNull(selector, "selector is null"); return OperatorPublish.create(this, selector, bufferSize); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final ConnectableObservable publish(int bufferSize) { validateBufferSize(bufferSize); return OperatorPublish.create(this, bufferSize); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable reduce(BiFunction reducer) { return scan(reducer).last(); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable reduce(R seed, BiFunction reducer) { return scan(seed, reducer).last(); } // Naming note, a plain scan would cause ambiguity with the value-seeded version @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable reduceWith(Supplier seedSupplier, BiFunction reducer) { return scanWith(seedSupplier, reducer).last(); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable repeat() { return repeat(Long.MAX_VALUE); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable repeat(long times) { if (times < 0) { throw new IllegalArgumentException("times >= 0 required but it was " + times); } if (times == 0) { return empty(); } return create(new PublisherRepeat(this, times)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable repeatUntil(BooleanSupplier stop) { Objects.requireNonNull(stop, "stop is null"); return create(new PublisherRepeatUntil(this, stop)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable repeatWhen(final Function, ? extends Publisher> handler) { Objects.requireNonNull(handler, "handler is null"); Function>>, Publisher> f = new Function>>, Publisher>() { @Override public Publisher apply(Observable>> no) { return handler.apply(no.map(new Function>, Object>() { @Override public Object apply(Try> v) { return 0; } })); } } ; return create(new PublisherRedo(this, f)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final ConnectableObservable replay() { return OperatorReplay.createFrom(this); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable replay(Function, ? extends Publisher> selector) { Objects.requireNonNull(selector, "selector is null"); return OperatorReplay.multicastSelector(new Supplier>() { @Override public ConnectableObservable get() { return replay(); } }, selector); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable replay(Function, ? extends Publisher> selector, final int bufferSize) { Objects.requireNonNull(selector, "selector is null"); return OperatorReplay.multicastSelector(new Supplier>() { @Override public ConnectableObservable get() { return replay(bufferSize); } }, selector); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable replay(Function, ? extends Publisher> selector, int bufferSize, long time, TimeUnit unit) { return replay(selector, bufferSize, time, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable replay(Function, ? extends Publisher> selector, final int bufferSize, final long time, final TimeUnit unit, final Scheduler scheduler) { if (bufferSize < 0) { throw new IllegalArgumentException("bufferSize < 0"); } Objects.requireNonNull(selector, "selector is null"); return OperatorReplay.multicastSelector(new Supplier>() { @Override public ConnectableObservable get() { return replay(bufferSize, time, unit, scheduler); } }, selector); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable replay(final Function, ? extends Publisher> selector, final int bufferSize, final Scheduler scheduler) { return OperatorReplay.multicastSelector(new Supplier>() { @Override public ConnectableObservable get() { return replay(bufferSize); } }, new Function, Publisher>() { @Override public Publisher apply(Observable t) { return fromPublisher(selector.apply(t)).observeOn(scheduler); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable replay(Function, ? extends Publisher> selector, long time, TimeUnit unit) { return replay(selector, time, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable replay(Function, ? extends Publisher> selector, final long time, final TimeUnit unit, final Scheduler scheduler) { Objects.requireNonNull(selector, "selector is null"); Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.multicastSelector(new Supplier>() { @Override public ConnectableObservable get() { return replay(time, unit, scheduler); } }, selector); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable replay(final Function, ? extends Publisher> selector, final Scheduler scheduler) { Objects.requireNonNull(selector, "selector is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.multicastSelector(new Supplier>() { @Override public ConnectableObservable get() { return replay(); } }, new Function, Publisher>() { @Override public Publisher apply(Observable t) { return fromPublisher(selector.apply(t)).observeOn(scheduler); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final ConnectableObservable replay(final int bufferSize) { return OperatorReplay.create(this, bufferSize); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final ConnectableObservable replay(int bufferSize, long time, TimeUnit unit) { return replay(bufferSize, time, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final int bufferSize, final long time, final TimeUnit unit, final Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); if (bufferSize < 0) { throw new IllegalArgumentException("bufferSize < 0"); } return OperatorReplay.create(this, time, unit, scheduler, bufferSize); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final int bufferSize, final Scheduler scheduler) { Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.observeOn(replay(bufferSize), scheduler); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final ConnectableObservable replay(long time, TimeUnit unit) { return replay(time, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final long time, final TimeUnit unit, final Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.create(this, time, unit, scheduler); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final ConnectableObservable replay(final Scheduler scheduler) { Objects.requireNonNull(scheduler, "scheduler is null"); return OperatorReplay.observeOn(replay(), scheduler); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry() { return retry(Long.MAX_VALUE, Functions.alwaysTrue()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry(BiPredicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return create(new PublisherRetryBiPredicate(this, predicate)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry(long times) { return retry(times, Functions.alwaysTrue()); } // Retries at most times or until the predicate returns false, whichever happens first @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry(long times, Predicate predicate) { if (times < 0) { throw new IllegalArgumentException("times >= 0 required but it was " + times); } Objects.requireNonNull(predicate, "predicate is null"); return create(new PublisherRetryPredicate(this, times, predicate)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retry(Predicate predicate) { return retry(Long.MAX_VALUE, predicate); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retryUntil(final BooleanSupplier stop) { Objects.requireNonNull(stop, "stop is null"); return retry(Long.MAX_VALUE, new Predicate() { @Override public boolean test(Throwable e) { return !stop.getAsBoolean(); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable retryWhen( final Function, ? extends Publisher> handler) { Objects.requireNonNull(handler, "handler is null"); Function>>, Publisher> f = new Function>>, Publisher>() { @Override public Publisher apply(Observable>> no) { Observable map = no.takeWhile(new Predicate>>() { @Override public boolean test(Try> e) { return e.hasError(); } }).map(new Function>, Throwable>() { @Override public Throwable apply(Try> t) { return t.error(); } }); return handler.apply(map); } } ; return create(new PublisherRedo(this, f)); } // TODO decide if safe subscription or unsafe should be the default @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final void safeSubscribe(Subscriber s) { Objects.requireNonNull(s, "s is null"); if (s instanceof SafeSubscriber) { subscribeActual(s); } else { subscribeActual(new SafeSubscriber(s)); } } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable sample(long period, TimeUnit unit) { return sample(period, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable sample(long period, TimeUnit unit, Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorSampleTimed(period, unit, scheduler)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable sample(Publisher sampler) { Objects.requireNonNull(sampler, "sampler is null"); return lift(new OperatorSamplePublisher(sampler)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable scan(BiFunction accumulator) { Objects.requireNonNull(accumulator, "accumulator is null"); return lift(new OperatorScan(accumulator)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable scan(final R seed, BiFunction accumulator) { Objects.requireNonNull(seed, "seed is null"); return scanWith(new Supplier() { @Override public R get() { return seed; } }, accumulator); } // Naming note, a plain scan would cause ambiguity with the value-seeded version @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable scanWith(Supplier seedSupplier, BiFunction accumulator) { Objects.requireNonNull(seedSupplier, "seedSupplier is null"); Objects.requireNonNull(accumulator, "accumulator is null"); return lift(new OperatorScanSeed(seedSupplier, accumulator)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable serialize() { return lift(new Operator() { @Override public Subscriber apply(Subscriber s) { return new SerializedSubscriber(s); } }); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable share() { return publish().refCount(); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable single() { return lift(OperatorSingle.instanceNoDefault()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable single(T defaultValue) { Objects.requireNonNull(defaultValue, "defaultValue is null"); return lift(new OperatorSingle(defaultValue)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable skip(long n) { // if (n < 0) { // throw new IllegalArgumentException("n >= 0 required but it was " + n); // } else // FIXME negative skip allowed?! if (n <= 0) { return this; } return lift(new OperatorSkip(n)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable skip(long time, TimeUnit unit, Scheduler scheduler) { // TODO consider inlining this behavior return skipUntil(timer(time, unit, scheduler)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable skipLast(int n) { if (n < 0) { throw new IndexOutOfBoundsException("n >= 0 required but it was " + n); } else if (n == 0) { return this; } return lift(new OperatorSkipLast(n)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable skipLast(long time, TimeUnit unit) { return skipLast(time, unit, Schedulers.trampoline(), false, bufferSize()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable skipLast(long time, TimeUnit unit, boolean delayError) { return skipLast(time, unit, Schedulers.trampoline(), delayError, bufferSize()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable skipLast(long time, TimeUnit unit, Scheduler scheduler) { return skipLast(time, unit, scheduler, false, bufferSize()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable skipLast(long time, TimeUnit unit, Scheduler scheduler, boolean delayError) { return skipLast(time, unit, scheduler, delayError, bufferSize()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable skipLast(long time, TimeUnit unit, Scheduler scheduler, boolean delayError, int bufferSize) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); // the internal buffer holds pairs of (timestamp, value) so double the default buffer size int s = bufferSize << 1; return lift(new OperatorSkipLastTimed(time, unit, scheduler, s, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable skipUntil(Publisher other) { Objects.requireNonNull(other, "other is null"); return lift(new OperatorSkipUntil(other)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable skipWhile(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return lift(new OperatorSkipWhile(predicate)); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable startWith(Iterable values) { return concatArray(fromIterable(values), this); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable startWith(Publisher other) { Objects.requireNonNull(other, "other is null"); return concatArray(other, this); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable startWith(T value) { Objects.requireNonNull(value, "value is null"); return concatArray(just(value), this); } @SuppressWarnings("unchecked") @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable startWithArray(T... values) { Observable fromArray = fromArray(values); if (fromArray == empty()) { return this; } return concatArray(fromArray, this); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe() { return subscribe(Functions.emptyConsumer(), RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), new Consumer() { @Override public void accept(Subscription s) { s.request(Long.MAX_VALUE); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext) { return subscribe(onNext, RxJavaPlugins.errorConsumer(), Functions.emptyRunnable(), new Consumer() { @Override public void accept(Subscription s) { s.request(Long.MAX_VALUE); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError) { return subscribe(onNext, onError, Functions.emptyRunnable(), new Consumer() { @Override public void accept(Subscription s) { s.request(Long.MAX_VALUE); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError, Runnable onComplete) { return subscribe(onNext, onError, onComplete, new Consumer() { @Override public void accept(Subscription s) { s.request(Long.MAX_VALUE); } }); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final Disposable subscribe(Consumer onNext, Consumer onError, Runnable onComplete, Consumer onSubscribe) { Objects.requireNonNull(onNext, "onNext is null"); Objects.requireNonNull(onError, "onError is null"); Objects.requireNonNull(onComplete, "onComplete is null"); Objects.requireNonNull(onSubscribe, "onSubscribe is null"); LambdaSubscriber ls = new LambdaSubscriber(onNext, onError, onComplete, onSubscribe); unsafeSubscribe(ls); return ls; } // TODO decide if safe subscription or unsafe should be the default @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) @Override public final void subscribe(Subscriber s) { Objects.requireNonNull(s, "s is null"); subscribeActual(s); } private void subscribeActual(Subscriber s) { try { s = RxJavaPlugins.onSubscribe(s); if (s == null) { throw new NullPointerException("Plugin returned null Subscriber"); } onSubscribe.subscribe(s); } catch (NullPointerException e) { throw e; } catch (Throwable e) { // TODO throw if fatal? // can't call onError because no way to know if a Subscription has been set or not // can't call onSubscribe because the call might have set a Subscription already RxJavaPlugins.onError(e); NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS"); npe.initCause(e); throw npe; } } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable subscribeOn(Scheduler scheduler) { return subscribeOn(scheduler, true); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable subscribeOn(Scheduler scheduler, boolean requestOn) { Objects.requireNonNull(scheduler, "scheduler is null"); return create(new PublisherSubscribeOn(this, scheduler, requestOn)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable switchIfEmpty(Publisher other) { Objects.requireNonNull(other, "other is null"); return lift(new OperatorSwitchIfEmpty(other)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable switchMap(Function> mapper) { return switchMap(mapper, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable switchMap(Function> mapper, int bufferSize) { Objects.requireNonNull(mapper, "mapper is null"); validateBufferSize(bufferSize); return lift(new OperatorSwitchMap(mapper, bufferSize)); } @BackpressureSupport(BackpressureKind.SPECIAL) // may trigger UNBOUNDED_IN @SchedulerSupport(SchedulerKind.NONE) public final Observable take(long n) { if (n < 0) { throw new IllegalArgumentException("n >= required but it was " + n); } else if (n == 0) { // FIXME may want to subscribe an cancel immediately // return lift(s -> CancelledSubscriber.INSTANCE); return empty(); } return lift(new OperatorTake(n)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable take(long time, TimeUnit unit, Scheduler scheduler) { // TODO consider inlining this behavior return takeUntil(timer(time, unit, scheduler)); } @BackpressureSupport(BackpressureKind.SPECIAL) // may trigger UNBOUNDED_IN @SchedulerSupport(SchedulerKind.NONE) public final Observable takeFirst(Predicate predicate) { return filter(predicate).take(1); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable takeLast(int n) { if (n < 0) { throw new IndexOutOfBoundsException("n >= required but it was " + n); } else if (n == 0) { return ignoreElements(); } else if (n == 1) { return lift(OperatorTakeLastOne.instance()); } return lift(new OperatorTakeLast(n)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable takeLast(long count, long time, TimeUnit unit) { return takeLast(count, time, unit, Schedulers.trampoline(), false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable takeLast(long count, long time, TimeUnit unit, Scheduler scheduler) { return takeLast(count, time, unit, scheduler, false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable takeLast(long count, long time, TimeUnit unit, Scheduler scheduler, boolean delayError, int bufferSize) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); validateBufferSize(bufferSize); if (count < 0) { throw new IndexOutOfBoundsException("count >= 0 required but it was " + count); } return lift(new OperatorTakeLastTimed(count, time, unit, scheduler, bufferSize, delayError)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable takeLast(long time, TimeUnit unit) { return takeLast(time, unit, Schedulers.trampoline(), false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable takeLast(long time, TimeUnit unit, boolean delayError) { return takeLast(time, unit, Schedulers.trampoline(), delayError, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable takeLast(long time, TimeUnit unit, Scheduler scheduler) { return takeLast(time, unit, scheduler, false, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable takeLast(long time, TimeUnit unit, Scheduler scheduler, boolean delayError) { return takeLast(time, unit, scheduler, delayError, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable takeLast(long time, TimeUnit unit, Scheduler scheduler, boolean delayError, int bufferSize) { return takeLast(Long.MAX_VALUE, time, unit, scheduler, delayError, bufferSize); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> takeLastBuffer(int count) { return takeLast(count).toList(); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable> takeLastBuffer(int count, long time, TimeUnit unit) { return takeLast(count, time, unit).toList(); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> takeLastBuffer(int count, long time, TimeUnit unit, Scheduler scheduler) { return takeLast(count, time, unit, scheduler).toList(); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable> takeLastBuffer(long time, TimeUnit unit) { return takeLast(time, unit).toList(); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> takeLastBuffer(long time, TimeUnit unit, Scheduler scheduler) { return takeLast(time, unit, scheduler).toList(); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable takeUntil(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return lift(new OperatorTakeUntilPredicate(predicate)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable takeUntil(Publisher other) { Objects.requireNonNull(other, "other is null"); return lift(new OperatorTakeUntil(other)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable takeWhile(Predicate predicate) { Objects.requireNonNull(predicate, "predicate is null"); return lift(new OperatorTakeWhile(predicate)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable throttleFirst(long windowDuration, TimeUnit unit) { return throttleFirst(windowDuration, unit, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable throttleFirst(long skipDuration, TimeUnit unit, Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorThrottleFirstTimed(skipDuration, unit, scheduler)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable throttleLast(long intervalDuration, TimeUnit unit) { return sample(intervalDuration, unit); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable throttleLast(long intervalDuration, TimeUnit unit, Scheduler scheduler) { return sample(intervalDuration, unit, scheduler); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable throttleWithTimeout(long timeout, TimeUnit unit) { return debounce(timeout, unit); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable throttleWithTimeout(long timeout, TimeUnit unit, Scheduler scheduler) { return debounce(timeout, unit, scheduler); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable> timeInterval() { return timeInterval(TimeUnit.MILLISECONDS, Schedulers.trampoline()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> timeInterval(Scheduler scheduler) { return timeInterval(TimeUnit.MILLISECONDS, scheduler); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable> timeInterval(TimeUnit unit) { return timeInterval(unit, Schedulers.trampoline()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> timeInterval(TimeUnit unit, Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorTimeInterval(unit, scheduler)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable timeout(Function> timeoutSelector) { return timeout0(null, timeoutSelector, null); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable timeout(Function> timeoutSelector, Observable other) { Objects.requireNonNull(other, "other is null"); return timeout0(null, timeoutSelector, other); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable timeout(long timeout, TimeUnit timeUnit) { return timeout0(timeout, timeUnit, null, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable timeout(long timeout, TimeUnit timeUnit, Observable other) { Objects.requireNonNull(other, "other is null"); return timeout0(timeout, timeUnit, other, Schedulers.computation()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable timeout(long timeout, TimeUnit timeUnit, Observable other, Scheduler scheduler) { Objects.requireNonNull(other, "other is null"); return timeout0(timeout, timeUnit, other, scheduler); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable timeout(long timeout, TimeUnit timeUnit, Scheduler scheduler) { return timeout0(timeout, timeUnit, null, scheduler); } public final Observable timeout(Supplier> firstTimeoutSelector, Function> timeoutSelector) { Objects.requireNonNull(firstTimeoutSelector, "firstTimeoutSelector is null"); return timeout0(firstTimeoutSelector, timeoutSelector, null); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable timeout( Supplier> firstTimeoutSelector, Function> timeoutSelector, Publisher other) { Objects.requireNonNull(firstTimeoutSelector, "firstTimeoutSelector is null"); Objects.requireNonNull(other, "other is null"); return timeout0(firstTimeoutSelector, timeoutSelector, other); } private Observable timeout0(long timeout, TimeUnit timeUnit, Observable other, Scheduler scheduler) { Objects.requireNonNull(timeUnit, "timeUnit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorTimeoutTimed(timeout, timeUnit, scheduler, other)); } private Observable timeout0( Supplier> firstTimeoutSelector, Function> timeoutSelector, Publisher other) { Objects.requireNonNull(timeoutSelector, "timeoutSelector is null"); return lift(new OperatorTimeout(firstTimeoutSelector, timeoutSelector, other)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable> timestamp() { return timestamp(TimeUnit.MILLISECONDS, Schedulers.trampoline()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> timestamp(Scheduler scheduler) { return timestamp(TimeUnit.MILLISECONDS, scheduler); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.TRAMPOLINE) public final Observable> timestamp(TimeUnit unit) { return timestamp(unit, Schedulers.trampoline()); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> timestamp(final TimeUnit unit, final Scheduler scheduler) { Objects.requireNonNull(unit, "unit is null"); Objects.requireNonNull(scheduler, "scheduler is null"); return map(new Function>() { @Override public Timed apply(T v) { return new Timed(v, scheduler.now(unit), unit); } }); } // TODO generics @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final R to(Function, R> converter) { return converter.apply(this); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) public final BlockingObservable toBlocking() { return BlockingObservable.from(this); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toList() { return lift(OperatorToList.defaultInstance()); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toList(final int capacityHint) { if (capacityHint <= 0) { throw new IllegalArgumentException("capacityHint > 0 required but it was " + capacityHint); } return lift(new OperatorToList>(new Supplier>() { @Override public List get() { return new ArrayList(capacityHint); } })); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final > Observable toList(Supplier collectionSupplier) { Objects.requireNonNull(collectionSupplier, "collectionSupplier is null"); return lift(new OperatorToList(collectionSupplier)); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toMap(final Function keySelector) { Objects.requireNonNull(keySelector, "keySelector is null"); return collect(new Supplier>() { @Override public Map get() { return new HashMap(); } }, new BiConsumer, T>() { @Override public void accept(Map m, T t) { K key = keySelector.apply(t); m.put(key, t); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toMap(final Function keySelector, final Function valueSelector) { Objects.requireNonNull(keySelector, "keySelector is null"); Objects.requireNonNull(valueSelector, "valueSelector is null"); return collect(new Supplier>() { @Override public Map get() { return new HashMap(); } }, new BiConsumer, T>() { @Override public void accept(Map m, T t) { K key = keySelector.apply(t); V value = valueSelector.apply(t); m.put(key, value); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toMap(final Function keySelector, final Function valueSelector, final Supplier> mapSupplier) { Objects.requireNonNull(keySelector, "keySelector is null"); Objects.requireNonNull(valueSelector, "valueSelector is null"); return collect(mapSupplier, new BiConsumer, T>() { @Override public void accept(Map m, T t) { K key = keySelector.apply(t); V value = valueSelector.apply(t); m.put(key, value); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable>> toMultimap(Function keySelector) { Function valueSelector = Functions.identity(); Supplier>> mapSupplier = new Supplier>>() { @Override public Map> get() { return new HashMap>(); } }; Function> collectionFactory = new Function>() { @Override public Collection apply(K k) { return new ArrayList(); } }; return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable>> toMultimap(Function keySelector, Function valueSelector) { Supplier>> mapSupplier = new Supplier>>() { @Override public Map> get() { return new HashMap>(); } }; Function> collectionFactory = new Function>() { @Override public Collection apply(K k) { return new ArrayList(); } }; return toMultimap(keySelector, valueSelector, mapSupplier, collectionFactory); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings("unchecked") public final Observable>> toMultimap( final Function keySelector, final Function valueSelector, final Supplier>> mapSupplier, final Function> collectionFactory) { Objects.requireNonNull(keySelector, "keySelector is null"); Objects.requireNonNull(valueSelector, "valueSelector is null"); Objects.requireNonNull(mapSupplier, "mapSupplier is null"); Objects.requireNonNull(collectionFactory, "collectionFactory is null"); return collect(mapSupplier, new BiConsumer>, T>() { @Override public void accept(Map> m, T t) { K key = keySelector.apply(t); Collection coll = m.get(key); if (coll == null) { coll = (Collection)collectionFactory.apply(key); m.put(key, coll); } V value = valueSelector.apply(t); coll.add(value); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable>> toMultimap( Function keySelector, Function valueSelector, Supplier>> mapSupplier ) { return toMultimap(keySelector, valueSelector, mapSupplier, new Function>() { @Override public Collection apply(K k) { return new ArrayList(); } }); } @BackpressureSupport(BackpressureKind.NONE) @SchedulerSupport(SchedulerKind.NONE) public final NbpObservable toNbpObservable() { return NbpObservable.fromPublisher(this); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Single toSingle() { return Single.fromPublisher(this); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings({ "unchecked", "rawtypes"}) public final Observable> toSortedList() { return toSortedList(new Comparator() { @Override public int compare(T o1, T o2) { return ((Comparable)o1).compareTo(o2); } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toSortedList(final Comparator comparator) { Objects.requireNonNull(comparator, "comparator is null"); return toList().map(new Function, List>() { @Override public List apply(List v) { Collections.sort(v, comparator); return v; } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) public final Observable> toSortedList(final Comparator comparator, int capacityHint) { Objects.requireNonNull(comparator, "comparator is null"); return toList(capacityHint).map(new Function, List>() { @Override public List apply(List v) { Collections.sort(v, comparator); return v; } }); } @BackpressureSupport(BackpressureKind.UNBOUNDED_IN) @SchedulerSupport(SchedulerKind.NONE) @SuppressWarnings({ "unchecked", "rawtypes"}) public final Observable> toSortedList(int capacityHint) { return toSortedList(new Comparator() { @Override public int compare(T o1, T o2) { return ((Comparable)o1).compareTo(o2); } }, capacityHint); } @BackpressureSupport(BackpressureKind.SPECIAL) @SchedulerSupport(SchedulerKind.NONE) // TODO decide if safe subscription or unsafe should be the default public final void unsafeSubscribe(Subscriber s) { Objects.requireNonNull(s, "s is null"); subscribeActual(s); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable unsubscribeOn(Scheduler scheduler) { Objects.requireNonNull(scheduler, "scheduler is null"); return lift(new OperatorUnsubscribeOn(scheduler)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(long count) { return window(count, count, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(long count, long skip) { return window(count, skip, bufferSize()); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(long count, long skip, int bufferSize) { if (skip <= 0) { throw new IllegalArgumentException("skip > 0 required but it was " + skip); } if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } validateBufferSize(bufferSize); return lift(new OperatorWindow(count, skip, bufferSize)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> window(long timespan, long timeskip, TimeUnit unit) { return window(timespan, timeskip, unit, Schedulers.computation(), bufferSize()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> window(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler) { return window(timespan, timeskip, unit, scheduler, bufferSize()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> window(long timespan, long timeskip, TimeUnit unit, Scheduler scheduler, int bufferSize) { validateBufferSize(bufferSize); Objects.requireNonNull(scheduler, "scheduler is null"); Objects.requireNonNull(unit, "unit is null"); return lift(new OperatorWindowTimed(timespan, timeskip, unit, scheduler, Long.MAX_VALUE, bufferSize, false)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> window(long timespan, TimeUnit unit) { return window(timespan, unit, Schedulers.computation(), Long.MAX_VALUE, false); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> window(long timespan, TimeUnit unit, long count) { return window(timespan, unit, Schedulers.computation(), count, false); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.COMPUTATION) public final Observable> window(long timespan, TimeUnit unit, long count, boolean restart) { return window(timespan, unit, Schedulers.computation(), count, restart); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> window(long timespan, TimeUnit unit, Scheduler scheduler) { return window(timespan, unit, scheduler, Long.MAX_VALUE, false); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> window(long timespan, TimeUnit unit, Scheduler scheduler, long count) { return window(timespan, unit, scheduler, count, false); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> window(long timespan, TimeUnit unit, Scheduler scheduler, long count, boolean restart) { return window(timespan, unit, scheduler, count, restart, bufferSize()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.CUSTOM) public final Observable> window( long timespan, TimeUnit unit, Scheduler scheduler, long count, boolean restart, int bufferSize) { validateBufferSize(bufferSize); Objects.requireNonNull(scheduler, "scheduler is null"); Objects.requireNonNull(unit, "unit is null"); if (count <= 0) { throw new IllegalArgumentException("count > 0 required but it was " + count); } return lift(new OperatorWindowTimed(timespan, timespan, unit, scheduler, count, bufferSize, restart)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(Publisher boundary) { return window(boundary, bufferSize()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(Publisher boundary, int bufferSize) { Objects.requireNonNull(boundary, "boundary is null"); return lift(new OperatorWindowBoundary(boundary, bufferSize)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window( Publisher windowOpen, Function> windowClose) { return window(windowOpen, windowClose, bufferSize()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window( Publisher windowOpen, Function> windowClose, int bufferSize) { Objects.requireNonNull(windowOpen, "windowOpen is null"); Objects.requireNonNull(windowClose, "windowClose is null"); return lift(new OperatorWindowBoundarySelector(windowOpen, windowClose, bufferSize)); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(Supplier> boundary) { return window(boundary, bufferSize()); } @BackpressureSupport(BackpressureKind.ERROR) @SchedulerSupport(SchedulerKind.NONE) public final Observable> window(Supplier> boundary, int bufferSize) { Objects.requireNonNull(boundary, "boundary is null"); return lift(new OperatorWindowBoundarySupplier(boundary, bufferSize)); } @BackpressureSupport(BackpressureKind.PASS_THROUGH) @SchedulerSupport(SchedulerKind.NONE) public final Observable withLatestFrom(Publisher other, BiFunction combiner) { Objects.requireNonNull(other, "other is null"); Objects.requireNonNull(combiner, "combiner is null"); return lift(new OperatorWithLatestFrom(combiner, other)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable zipWith(Iterable other, BiFunction zipper) { Objects.requireNonNull(other, "other is null"); Objects.requireNonNull(zipper, "zipper is null"); return create(new PublisherZipIterable(this, other, zipper)); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable zipWith(Publisher other, BiFunction zipper) { Objects.requireNonNull(other, "other is null"); return zip(this, other, zipper); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable zipWith(Publisher other, BiFunction zipper, boolean delayError) { return zip(this, other, zipper, delayError); } @BackpressureSupport(BackpressureKind.FULL) @SchedulerSupport(SchedulerKind.NONE) public final Observable zipWith(Publisher other, BiFunction zipper, boolean delayError, int bufferSize) { return zip(this, other, zipper, delayError, bufferSize); } }