@Override public CompletionStage<T> apply(T r, Throwable ex) { return (ex == null) ? thisStage : fn.apply(ex); } }).thenCompose(Functions.<CompletionStage<T>>identity());
/** * Returns a composed function that first applies the {@code before} * function to its input, and then applies the {@code this_} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <R> the type of the result of the {@code this_} function and of the composed function * @param <T> the type of the input to the {@code this_} and of the result of the {@code before} function * @param <V> the type of input to the {@code before} function, and to the * composed function * @param this_ the function to apply after the {@code before} function is applied * @param before the function to apply before the {@code this_} function is applied * @return a composed function that first applies the {@code before} * function and then applies the {@code this_} function * @throws NullPointerException if {@code this_} is null * @throws NullPointerException if before is null * * @see #andThen(Function, Function) */ public static <R, T, V> Function<V, R> compose(Function<? super T, ? extends R> this_, Function<? super V, ? extends T> before) { Objects.requireNonNull(this_); Objects.requireNonNull(before); return (V v) -> this_.apply(before.apply(v)); }
/** * Returns a composed function that first applies the {@code this_} function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <R> the type of the result of the {@code this_} function and of the input to the {@code after} function. * @param <T> the type of the input to the {@code this_} function and to the composed function * @param <V> the type of output of the {@code after} function, and of the * composed function * @param this_ the function to apply before the {@code after} function is applied * @param after the function to apply after the {@code this_} function is applied * @return a composed function that first applies the {@code this_} function and then * applies the {@code after} function * @throws NullPointerException if {@code this_} is null * @throws NullPointerException if after is null * * @see #compose(Function, Function) */ public static <R, T, V> Function<T, V> andThen(Function<? super T, ? extends R> this_, Function<? super R, ? extends V> after) { Objects.requireNonNull(this_); Objects.requireNonNull(after); return (T t) -> after.apply(this_.apply(t)); }
/** * Returns a composed function that first applies the {@code before} * function to its input, and then applies the {@code this_} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <R> the type of the result of the {@code this_} function and of the composed function * @param <T> the type of the input to the {@code this_} and of the result of the {@code before} function * @param <V> the type of input to the {@code before} function, and to the * composed function * @param this_ the function to apply after the {@code before} function is applied * @param before the function to apply before the {@code this_} function is applied * @return a composed function that first applies the {@code before} * function and then applies the {@code this_} function * @throws NullPointerException if {@code this_} is null * @throws NullPointerException if before is null * * @see #andThen(Function, Function) */ public static <R, T, V> Function<V, R> compose(Function<? super T, ? extends R> this_, Function<? super V, ? extends T> before) { Objects.requireNonNull(this_); Objects.requireNonNull(before); return (V v) -> this_.apply(before.apply(v)); }
/** * Returns a composed function that first applies the {@code this_} function to * its input, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <R> the type of the result of the {@code this_} function and of the input to the {@code after} function. * @param <T> the type of the input to the {@code this_} function and to the composed function * @param <V> the type of output of the {@code after} function, and of the * composed function * @param this_ the function to apply before the {@code after} function is applied * @param after the function to apply after the {@code this_} function is applied * @return a composed function that first applies the {@code this_} function and then * applies the {@code after} function * @throws NullPointerException if {@code this_} is null * @throws NullPointerException if after is null * * @see #compose(Function, Function) */ public static <R, T, V> Function<T, V> andThen(Function<? super T, ? extends R> this_, Function<? super R, ? extends V> after) { Objects.requireNonNull(this_); Objects.requireNonNull(after); return (T t) -> after.apply(this_.apply(t)); }
/** * {@code BiConsumer<Map, T>} that accumulates (key, value) pairs * extracted from elements into the map, throwing {@code IllegalStateException} * if duplicate keys are encountered. * * @param keyMapper a function that maps an element into a key * @param valueMapper a function that maps an element into a value * @param <T> type of elements * @param <K> type of map keys * @param <V> type of map values * @return an accumulating consumer */ private static <T, K, V> BiConsumer<Map<K, V>, T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) { return (map, element) -> { K k = keyMapper.apply(element); V v = Objects.requireNonNull(valueMapper.apply(element)); V u = null; if (map instanceof ConcurrentMap) { u = ((ConcurrentMap<K, V>) map).putIfAbsent(k, v); } else { u = Maps.putIfAbsent(map, k, v); } if (u != null) { throw duplicateKeyException(k, u, v); } }; }
/** * {@code BiConsumer<Map, T>} that accumulates (key, value) pairs * extracted from elements into the map, throwing {@code IllegalStateException} * if duplicate keys are encountered. * * @param keyMapper a function that maps an element into a key * @param valueMapper a function that maps an element into a value * @param <T> type of elements * @param <K> type of map keys * @param <V> type of map values * @return an accumulating consumer */ private static <T, K, V> BiConsumer<Map<K, V>, T> uniqKeysMapAccumulator(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends V> valueMapper) { return (map, element) -> { K k = keyMapper.apply(element); V v = Objects.requireNonNull(valueMapper.apply(element)); V u = null; if (map instanceof ConcurrentMap) { u = ((ConcurrentMap<K, V>) map).putIfAbsent(k, v); } else { u = Maps.putIfAbsent(map, k, v); } if (u != null) { throw duplicateKeyException(k, u, v); } }; }
/** * Returns a composed function that first applies the {@code this_} function to * its inputs, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <R> the type of the result of the {@code this_} function and the type of the input of the {@code after} function. * @param <T> the type of the first argument to the {@code this_} function * @param <U> the type of the second argument to the {@code this_} function * @param <V> the type of output of the {@code after} function, and of the * composed function * @param this_ the {@code BiFunction} to be applied first. * @param after the function to apply after the {@code this_} function is applied * @return a composed function that first applies the {@code this_} function and then * applies the {@code after} function * @throws NullPointerException if {@code this_} is null * @throws NullPointerException if after is null */ public static <R, T, U, V> BiFunction<T, U, V> andThen(BiFunction<? super T, ? super U, ? extends R> this_, Function<? super R, ? extends V> after) { Objects.requireNonNull(this_); Objects.requireNonNull(after); return (T t, U u) -> after.apply(this_.apply(t, u)); }
/** * Returns a composed function that first applies the {@code this_} function to * its inputs, and then applies the {@code after} function to the result. * If evaluation of either function throws an exception, it is relayed to * the caller of the composed function. * * @param <R> the type of the result of the {@code this_} function and the type of the input of the {@code after} function. * @param <T> the type of the first argument to the {@code this_} function * @param <U> the type of the second argument to the {@code this_} function * @param <V> the type of output of the {@code after} function, and of the * composed function * @param this_ the {@code BiFunction} to be applied first. * @param after the function to apply after the {@code this_} function is applied * @return a composed function that first applies the {@code this_} function and then * applies the {@code after} function * @throws NullPointerException if {@code this_} is null * @throws NullPointerException if after is null */ public static <R, T, U, V> BiFunction<T, U, V> andThen(BiFunction<? super T, ? super U, ? extends R> this_, Function<? super R, ? extends V> after) { Objects.requireNonNull(this_); Objects.requireNonNull(after); return (T t, U u) -> after.apply(this_.apply(t, u)); }
final boolean uniExceptionally(Object r, Function<? super Throwable, ? extends T> f, UniExceptionally<T> c) { Throwable x; if (result == null) { try { if (c != null && !c.claim()) return false; if (r instanceof AltResult && (x = ((AltResult)r).ex) != null) completeValue(f.apply(x)); else internalComplete(r); } catch (Throwable ex) { completeThrowable(ex); } } return true; }
private <V> CompletableFuture<V> uniApplyNow( Object r, Executor e, Function<? super T,? extends V> f) { Throwable x; CompletableFuture<V> d = newIncompleteFuture(); if (r instanceof AltResult) { if ((x = ((AltResult)r).ex) != null) { d.result = encodeThrowable(x, r); return d; } r = null; } try { if (e != null) { e.execute(new UniApply<T,V>(null, d, this, f)); } else { @SuppressWarnings("unchecked") T t = (T) r; d.result = d.encodeValue(f.apply(t)); } } catch (Throwable ex) { d.result = encodeThrowable(ex); } return d; }
/** * If a value is present, returns the result of applying the given * {@code Optional}-bearing mapping function to the value, otherwise returns * an empty {@code Optional}. * * <p>This method is similar to {@link #map(Function)}, but the mapping * function is one whose result is already an {@code Optional}, and if * invoked, {@code flatMap} does not wrap it within an additional * {@code Optional}. * * @param <U> The type of value of the {@code Optional} returned by the * mapping function * @param mapper the mapping function to apply to a value, if present * @return the result of applying an {@code Optional}-bearing mapping * function to the value of this {@code Optional}, if a value is * present, otherwise an empty {@code Optional} * @throws NullPointerException if the mapping function is {@code null} or * returns a {@code null} result */ public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) { return empty(); } else { @SuppressWarnings("unchecked") Optional<U> r = (Optional<U>) mapper.apply(value); return Objects.requireNonNull(r); } }
/** * If a value is present, returns the result of applying the given * {@code Optional}-bearing mapping function to the value, otherwise returns * an empty {@code Optional}. * * <p>This method is similar to {@link #map(Function)}, but the mapping * function is one whose result is already an {@code Optional}, and if * invoked, {@code flatMap} does not wrap it within an additional * {@code Optional}. * * @param <U> The type of value of the {@code Optional} returned by the * mapping function * @param mapper the mapping function to apply to a value, if present * @return the result of applying an {@code Optional}-bearing mapping * function to the value of this {@code Optional}, if a value is * present, otherwise an empty {@code Optional} * @throws NullPointerException if the mapping function is {@code null} or * returns a {@code null} result */ public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) { return empty(); } else { @SuppressWarnings("unchecked") Optional<U> r = (Optional<U>) mapper.apply(value); return Objects.requireNonNull(r); } }
@Override @SuppressWarnings("unchecked") public final <R, A> R collect(Collector<? super P_OUT, A, R> collector) { A container; if (isParallel() && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT)) && (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) { container = collector.supplier().get(); BiConsumer<A, ? super P_OUT> accumulator = collector.accumulator(); forEach(u -> accumulator.accept(container, u)); } else { container = evaluate(ReduceOps.makeRef(collector)); } return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH) ? (R) container : collector.finisher().apply(container); }
@Override @SuppressWarnings("unchecked") public final <R, A> R collect(Collector<? super P_OUT, A, R> collector) { A container; if (isParallel() && (collector.characteristics().contains(Collector.Characteristics.CONCURRENT)) && (!isOrdered() || collector.characteristics().contains(Collector.Characteristics.UNORDERED))) { container = collector.supplier().get(); BiConsumer<A, ? super P_OUT> accumulator = collector.accumulator(); forEach(u -> accumulator.accept(container, u)); } else { container = evaluate(ReduceOps.makeRef(collector)); } return collector.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH) ? (R) container : collector.finisher().apply(container); }
final CompletableFuture<V> tryFire(int mode) { CompletableFuture<V> d; CompletableFuture<T> a; Object r; Throwable x; Function<? super T,? extends V> f; if ((d = dep) == null || (f = fn) == null || (a = src) == null || (r = a.result) == null) return null; tryComplete: if (d.result == null) { if (r instanceof AltResult) { if ((x = ((AltResult)r).ex) != null) { d.completeThrowable(x, r); break tryComplete; } r = null; } try { if (mode <= 0 && !claim()) return null; else { @SuppressWarnings("unchecked") T t = (T) r; d.completeValue(f.apply(t)); } } catch (Throwable ex) { d.completeThrowable(ex); } } dep = null; src = null; fn = null; return d.postFire(a, mode); } }
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator(); return new CollectorImpl<>(downstream.supplier(), (r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)), downstream.combiner(), downstream.finisher(), downstream.characteristics());
private CompletableFuture<T> uniComposeExceptionallyStage( Executor e, Function<Throwable, ? extends CompletionStage<T>> f) { Objects.requireNonNull(f); CompletableFuture<T> d = newIncompleteFuture(); Object r, s; Throwable x; if ((r = result) == null) unipush(new UniComposeExceptionally<T>(e, d, this, f)); else if (!(r instanceof AltResult) || (x = ((AltResult) r).ex) == null) d.internalComplete(r); else try { if (e != null) e.execute(new UniComposeExceptionally<T>(null, d, this, f)); else { CompletableFuture<T> g = f.apply(x).toCompletableFuture(); if ((s = g.result) != null) d.result = encodeRelay(s); else g.unipush(new UniRelay<T,T>(d, g)); } } catch (Throwable ex) { d.result = encodeThrowable(ex); } return d; }