|
13 | 13 |
|
14 | 14 | package io.reactivex.rxjava3.core;
|
15 | 15 |
|
16 |
| -import java.util.NoSuchElementException; |
17 |
| -import java.util.Objects; |
| 16 | +import java.util.*; |
18 | 17 | import java.util.concurrent.*;
|
19 | 18 |
|
20 | 19 | import org.reactivestreams.*;
|
|
25 | 24 | import io.reactivex.rxjava3.functions.*;
|
26 | 25 | import io.reactivex.rxjava3.internal.functions.*;
|
27 | 26 | import io.reactivex.rxjava3.internal.fuseable.*;
|
| 27 | +import io.reactivex.rxjava3.internal.jdk8.*; |
28 | 28 | import io.reactivex.rxjava3.internal.observers.BlockingMultiObserver;
|
29 | 29 | import io.reactivex.rxjava3.internal.operators.flowable.*;
|
30 | 30 | import io.reactivex.rxjava3.internal.operators.maybe.*;
|
@@ -4794,4 +4794,162 @@ public final TestObserver<T> test(boolean dispose) {
|
4794 | 4794 | subscribe(to);
|
4795 | 4795 | return to;
|
4796 | 4796 | }
|
| 4797 | + |
| 4798 | + // ------------------------------------------------------------------------- |
| 4799 | + // JDK 8 Support |
| 4800 | + // ------------------------------------------------------------------------- |
| 4801 | + |
| 4802 | + /** |
| 4803 | + * Converts the existing value of the provided optional into a {@link #just(Object)} |
| 4804 | + * or an empty optional into an {@link #empty()} {@code Maybe} instance. |
| 4805 | + * <p> |
| 4806 | + * <img width="640" height="335" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/fromOptional.m.png" alt=""> |
| 4807 | + * <p> |
| 4808 | + * Note that the operator takes an already instantiated optional reference and does not |
| 4809 | + * by any means create this original optional. If the optional is to be created per |
| 4810 | + * consumer upon subscription, use {@link #defer(Supplier)} around {@code fromOptional}: |
| 4811 | + * <pre><code> |
| 4812 | + * Maybe.defer(() -> Maybe.fromOptional(createOptional())); |
| 4813 | + * </code></pre> |
| 4814 | + * <dl> |
| 4815 | + * <dt><b>Scheduler:</b></dt> |
| 4816 | + * <dd>{@code fromOptional} does not operate by default on a particular {@link Scheduler}.</dd> |
| 4817 | + * </dl> |
| 4818 | + * @param <T> the element type of the optional value |
| 4819 | + * @param optional the optional value to convert into a {@code Maybe} |
| 4820 | + * @return the new Maybe instance |
| 4821 | + * @see #just(Object) |
| 4822 | + * @see #empty() |
| 4823 | + * @since 3.0.0 |
| 4824 | + */ |
| 4825 | + @CheckReturnValue |
| 4826 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 4827 | + @NonNull |
| 4828 | + public static <T> Maybe<@NonNull T> fromOptional(@NonNull Optional<T> optional) { |
| 4829 | + Objects.requireNonNull(optional, "optional is null"); |
| 4830 | + return optional.map(Maybe::just).orElseGet(Maybe::empty); |
| 4831 | + } |
| 4832 | + |
| 4833 | + /** |
| 4834 | + * Signals the completion value or error of the given (hot) {@link CompletionStage}-based asynchronous calculation. |
| 4835 | + * <p> |
| 4836 | + * <img width="640" height="262" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/fromCompletionStage.s.png" alt=""> |
| 4837 | + * <p> |
| 4838 | + * Note that the operator takes an already instantiated, running or terminated {@code CompletionStage}. |
| 4839 | + * If the optional is to be created per consumer upon subscription, use {@link #defer(Supplier)} |
| 4840 | + * around {@code fromCompletionStage}: |
| 4841 | + * <pre><code> |
| 4842 | + * Maybe.defer(() -> Maybe.fromCompletionStage(createCompletionStage())); |
| 4843 | + * </code></pre> |
| 4844 | + * <p> |
| 4845 | + * If the {@code CompletionStage} completes with {@code null}, the resulting {@code Maybe} is completed via {@code onComplete}. |
| 4846 | + * <p> |
| 4847 | + * Canceling the flow can't cancel the execution of the {@code CompletionStage} because {@code CompletionStage} |
| 4848 | + * itself doesn't support cancellation. Instead, the operator detaches from the {@code CompletionStage}. |
| 4849 | + * <dl> |
| 4850 | + * <dt><b>Scheduler:</b></dt> |
| 4851 | + * <dd>{@code fromCompletionStage} does not operate by default on a particular {@link Scheduler}.</dd> |
| 4852 | + * </dl> |
| 4853 | + * @param <T> the element type of the CompletionStage |
| 4854 | + * @param stage the CompletionStage to convert to Maybe and signal its terminal value or error |
| 4855 | + * @return the new Maybe instance |
| 4856 | + * @since 3.0.0 |
| 4857 | + */ |
| 4858 | + @CheckReturnValue |
| 4859 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 4860 | + @NonNull |
| 4861 | + public static <T> Maybe<@NonNull T> fromCompletionStage(@NonNull CompletionStage<T> stage) { |
| 4862 | + Objects.requireNonNull(stage, "stage is null"); |
| 4863 | + return RxJavaPlugins.onAssembly(new MaybeFromCompletionStage<>(stage)); |
| 4864 | + } |
| 4865 | + |
| 4866 | + /** |
| 4867 | + * Maps the upstream success value into an {@link Optional} and emits the contained item if not empty. |
| 4868 | + * <p> |
| 4869 | + * <img width="640" height="323" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/mapOptional.m.png" alt=""> |
| 4870 | + * |
| 4871 | + * <dl> |
| 4872 | + * <dt><b>Scheduler:</b></dt> |
| 4873 | + * <dd>{@code mapOptional} does not operate by default on a particular {@link Scheduler}.</dd> |
| 4874 | + * </dl> |
| 4875 | + * @param <R> the non-null output type |
| 4876 | + * @param mapper the function that receives the upstream success iteem and should return a <em>non-empty</em> {@code Optional} |
| 4877 | + * to emit as the success output or an <em>empty</em> {@code Optional} to complete the {@code Maybe} |
| 4878 | + * @return the new Maybe instance |
| 4879 | + * @since 3.0.0 |
| 4880 | + * @see #map(Function) |
| 4881 | + * @see #filter(Predicate) |
| 4882 | + */ |
| 4883 | + @CheckReturnValue |
| 4884 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 4885 | + @NonNull |
| 4886 | + public final <@NonNull R> Maybe<R> mapOptional(@NonNull Function<? super T, @NonNull Optional<? extends R>> mapper) { |
| 4887 | + Objects.requireNonNull(mapper, "mapper is null"); |
| 4888 | + return RxJavaPlugins.onAssembly(new MaybeMapOptional<>(this, mapper)); |
| 4889 | + } |
| 4890 | + |
| 4891 | + /** |
| 4892 | + * Signals the upstream success item (or a {@link NoSuchElementException} if the upstream is empty) via |
| 4893 | + * a {@link CompletionStage}. |
| 4894 | + * <p> |
| 4895 | + * <img width="640" height="349" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/toCompletionStage.m.png" alt=""> |
| 4896 | + * <p> |
| 4897 | + * The upstream can be canceled by converting the resulting {@code CompletionStage} into |
| 4898 | + * {@link CompletableFuture} via {@link CompletionStage#toCompletableFuture()} and |
| 4899 | + * calling {@link CompletableFuture#cancel(boolean)} on it. |
| 4900 | + * The upstream will be also cancelled if the resulting {@code CompletionStage} is converted to and |
| 4901 | + * completed manually by {@link CompletableFuture#complete(Object)} or {@link CompletableFuture#completeExceptionally(Throwable)}. |
| 4902 | + * <p> |
| 4903 | + * {@code CompletionStage}s don't have a notion of emptyness and allow {@code null}s, therefore, one can either use |
| 4904 | + * {@link #toCompletionStage(Object)} with {@code null} or turn the upstrea into a sequence of {@link Optional}s and |
| 4905 | + * default to {@link Optional#empty()}: |
| 4906 | + * <pre><code> |
| 4907 | + * CompletionStage<Optional<T>> stage = source.map(Optional::of).toCompletionStage(Optional.empty()); |
| 4908 | + * </code></pre> |
| 4909 | + * <dl> |
| 4910 | + * <dt><b>Scheduler:</b></dt> |
| 4911 | + * <dd>{@code toCompletionStage} does not operate by default on a particular {@link Scheduler}.</dd> |
| 4912 | + * </dl> |
| 4913 | + * @return the new CompletionStage instance |
| 4914 | + * @since 3.0.0 |
| 4915 | + * @see #toCompletionStage(Object) |
| 4916 | + */ |
| 4917 | + @CheckReturnValue |
| 4918 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 4919 | + @NonNull |
| 4920 | + public final CompletionStage<T> toCompletionStage() { |
| 4921 | + return subscribeWith(new CompletionStageConsumer<>(false, null)); |
| 4922 | + } |
| 4923 | + |
| 4924 | + /** |
| 4925 | + * Signals the upstream success item (or the default item if the upstream is empty) via |
| 4926 | + * a {@link CompletionStage}. |
| 4927 | + * <p> |
| 4928 | + * <img width="640" height="323" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/toCompletionStage.mv.png" alt=""> |
| 4929 | + * <p> |
| 4930 | + * The upstream can be canceled by converting the resulting {@code CompletionStage} into |
| 4931 | + * {@link CompletableFuture} via {@link CompletionStage#toCompletableFuture()} and |
| 4932 | + * calling {@link CompletableFuture#cancel(boolean)} on it. |
| 4933 | + * The upstream will be also cancelled if the resulting {@code CompletionStage} is converted to and |
| 4934 | + * completed manually by {@link CompletableFuture#complete(Object)} or {@link CompletableFuture#completeExceptionally(Throwable)}. |
| 4935 | + * <p> |
| 4936 | + * {@code CompletionStage}s don't have a notion of emptyness and allow {@code null}s, therefore, one can either use |
| 4937 | + * a {@code defaultItem} of {@code null} or turn the flow into a sequence of {@link Optional}s and default to {@link Optional#empty()}: |
| 4938 | + * <pre><code> |
| 4939 | + * CompletionStage<Optional<T>> stage = source.map(Optional::of).toCompletionStage(Optional.empty()); |
| 4940 | + * </code></pre> |
| 4941 | + * <dl> |
| 4942 | + * <dt><b>Scheduler:</b></dt> |
| 4943 | + * <dd>{@code toCompletionStage} does not operate by default on a particular {@link Scheduler}.</dd> |
| 4944 | + * </dl> |
| 4945 | + * @param defaultItem the item to signal if the upstream is empty |
| 4946 | + * @return the new CompletionStage instance |
| 4947 | + * @since 3.0.0 |
| 4948 | + */ |
| 4949 | + @CheckReturnValue |
| 4950 | + @SchedulerSupport(SchedulerSupport.NONE) |
| 4951 | + @NonNull |
| 4952 | + public final CompletionStage<T> toCompletionStage(@Nullable T defaultItem) { |
| 4953 | + return subscribeWith(new CompletionStageConsumer<>(true, defaultItem)); |
| 4954 | + } |
4797 | 4955 | }
|
0 commit comments