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

hu.akarnokd.rxjava2.interop.FlowableInterop Maven / Gradle / Ivy

/*
 * Copyright 2016 David Karnok
 *
 * 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.interop;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;

import io.reactivex.*;
import io.reactivex.functions.Function;
import io.reactivex.plugins.RxJavaPlugins;
import io.reactivex.processors.AsyncProcessor;

/**
 * Utility methods, sources and operators supporting RxJava 2 and the Jdk 8 API
 * interoperation.
 * 
 * @since 0.1.0
 */
public final class FlowableInterop {

    /** Utility class. */
    private FlowableInterop() {
        throw new IllegalStateException("No instances!");
    }

    /**
     * Wrap a Stream into a Flowable.
     * 

Note that Streams can only be consumed once and non-concurrently. * @param the value type * @param stream the source Stream * @return the new Flowable instance */ public static Flowable fromStream(Stream stream) { return Flowable.fromIterable(() -> stream.iterator()); } /** * Returns a Flowable for the value (or lack of) in the given Optional. * @param the value type * @param opt the optional to wrap * @return the new Flowable instance */ public static Flowable fromOptional(Optional opt) { return opt.map(Flowable::just).orElse(Flowable.empty()); } /** * Create a Flowable that signals the terminal value or error of the given * CompletionStage. *

Cancelling the Flowable subscription doesn't cancel the CompletionStage. * @param the value type * @param cs the CompletionStage instance * @return the new Flowable instance */ public static Flowable fromFuture(CompletionStage cs) { AsyncProcessor ap = AsyncProcessor.create(); cs.whenComplete((v, e) -> { if (e != null) { ap.onError(e); } else { ap.onNext(v); ap.onComplete(); } }); return ap; } /** * Collect the elements of the Flowable via the help of Collector and its callback * functions. * @param the upstream value type * @param the accumulated type * @param the result type * @param collector the Collector object providing the callbacks * @return the Transformer instance to be used with {@code Flowable.compose()} */ public static FlowableTransformer collect(Collector collector) { return f -> RxJavaPlugins.onAssembly(new FlowableCollector<>(f, collector)); } /** * Returns a CompletionStage that signals the first element of the Flowable * or a NoSuchElementException if the Flowable is empty. * @param the value type * @return the Function to be used via {@code Flowable.to}. */ public static Function, CompletionStage> first() { return f -> { CompletableFuture cf = new CompletableFuture<>(); f.firstOrError().subscribe(cf::complete, cf::completeExceptionally); return cf; }; } /** * Returns a CompletionStage that signals the single element of the Flowable, * IllegalArgumentException if the Flowable is longer than 1 element * or a NoSuchElementException if the Flowable is empty. * @param the value type * @return the Function to be used with {@code Flowable.to}. */ public static Function, CompletionStage> single() { return f -> { CompletableFuture cf = new CompletableFuture<>(); f.singleOrError().subscribe(cf::complete, cf::completeExceptionally); return cf; }; } /** * Returns a CompletionStage that emits the last element of the Flowable or * NoSuchElementException if the Flowable is empty. * @param the value type * @return the Function to be used with {@code Flowable.to}. */ public static Function, CompletionStage> last() { return f -> { CompletableFuture cf = new CompletableFuture<>(); f.lastOrError().subscribe(cf::complete, cf::completeExceptionally); return cf; }; } /** * Returns a blocking Stream of the elements of the Flowable. *

* Closing the Stream will cancel the flow. * @param the value type * @return the Function to be used with {@code Flowable.to}. */ public static Function, Stream> toStream() { return f -> ZeroOneIterator.toStream(f.blockingIterable().iterator()); } /** * Block until the source Flowable emits its first item and return that as Optional. * @param the value type * @return the converter Function to be used with {@code Flowable.to()}. */ public static Function, Optional> firstElement() { return f -> Optional.ofNullable(f.blockingFirst(null)); } /** * Block until the source Flowable completes and return its last value as Optional. * @param the value type * @return the converter Function to be used with {@code Flowable.to()}. */ public static Function, Optional> lastElement() { return f -> Optional.ofNullable(f.blockingLast(null)); } /** * Map each value of the upstream into a Stream and flatten them into a single sequence. * @param the input value type * @param the Stream type * @param mapper the function that returns a Stream for each upstream value * @return the Transformer instance to be used with {@code Flowable.compose()} */ public static FlowableTransformer flatMapStream(Function> mapper) { return f -> f.flatMapIterable(v -> { Iterator it = mapper.apply(v).iterator(); return () -> it; }); } /** * Maps the upstream value into an optional and extracts its optional value to be emitted towards * the downstream if present. * @param the upstream value type * @param the result value type * @param mapper the function receiving the upstream value and should return an Optional * @return the Transformer instance to be used with {@code Flowable.compose()} */ public static FlowableTransformer mapOptional(Function> mapper) { return f -> RxJavaPlugins.onAssembly(new FlowableMapOptional<>(f, mapper)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy