/** * Chains the output of one function into the input of another, thereby creating a new * function. * * @see CheckedFunction#andThen(CheckedFunction) * * @param <U> Initial input type of the {@code before} function. * @param <V> Output type of the {@code before} function and the input of {@code after}. * @param <W> Output type of the {@code after} function. * @param <X> Exception type. * @param before The initial function. * @param after The function to chain to. * @return A composite {@link CheckedFunction}. * @throws X If an error occurs. */ public static <U, V, W, X extends Throwable> CheckedFunction<U, W, X> chain(CheckedFunction<U, V, X> before, CheckedFunction<V, W, X> after) throws X { return before.andThen(after); }
/** * Evaluates a given {@code mapper} function, passing it the given {@code value} if the latter * is non-{@code null}, returning the mapped value. Otherwise, if the given {@code value} is * {@code null}, a {@code null} is returned. This is the functional equivalent of the * Elvis operator. <p> * * Note: as the mapping function is free to output {@code null}, this method can return a * {@code null} for a non-{@code null} input value. * * @param <T> Value type. * @param <U> Mapped type. * @param <X> Exception type. * @param value The value to map, if it isn't {@code null}. * @param mapper The mapping function to invoke if the value isn't {@code null}. * @return The mapped value if the initial value isn't {@code null}, or {@code null} otherwise. * @throws X If an error occurs inside the mapping function. */ public static <T, U, X extends Throwable> U ifPresent(T value, CheckedFunction<? super T, ? extends U, X> mapper) throws X { return value != null ? mapper.apply(value) : null; }
/** * Maps elements from the {@code source} collection to a new collection instance, * using the given mapping function. * * @param <U> Source element type. * @param <V> Target element type. * @param <C> Target collection type. * @param <X> Exception type. * @param source The source collection. * @param mapper The mapping function applied to elements. * @param collectionMaker A way of creating a new collection to store the mapped elements. * @return The target collection. * @throws X If an error occurs within the mapping function. */ public static <U, V, C extends Collection<V>, X extends Throwable> C mapCollection(Collection<? extends U> source, CheckedFunction<? super U, ? extends V, ? extends X> mapper, Supplier<C> collectionMaker) throws X { if (source != null) { final C mapped = collectionMaker.get(); for (U item : source) { mapped.add(mapper.apply(item)); } return mapped; } else { return null; } }
/** * Applies a function to the result of a supplier, thereby creating a new supplier. * * @param <U> Original type supplied by {@code before} and input to the {@code after} function. * @param <V> Output type of the {@code after} function. * @param <X> Exception type. * @param before The original value supplier. * @param after The transformation to apply to the supplied value. * @return A composite {@link CheckedSupplier}. * @throws X If an error occurs. */ public static <U, V, X extends Throwable> CheckedSupplier<V, X> chain(CheckedSupplier<U, ? extends X> before, CheckedFunction<U, V, ? extends X> after) throws X { return () -> after.apply(before.get()); }
/** * Chains the output of a function into the input of a consumer, thereby creating a new * consumer. * * @param <U> Input type of the {@code before} function. * @param <V> Output type of the {@code before} function and input type of the {@code after} consumer. * @param <X> Exception type. * @param before The initial function to apply. * @param after The consumer to chain to. * @return A composite {@link CheckedConsumer}. * @throws X If an error occurs. */ public static <U, V, X extends Throwable> CheckedConsumer<U, X> chain(CheckedFunction<U, V, X> before, CheckedConsumer<V, X> after) throws X { return u -> after.accept(before.apply(u)); }
/** * Maps values from the {@code source} map to a new map instance, using the given * mapping function. The mapping function only works on the values; * the keys are copied as-is. * * @param <K> Key type. * @param <U> Source value type. * @param <V> Target value type. * @param <M> Target map type. * @param <X> Exception type. * @param source The source map. * @param mapper The mapping function applied to values. * @param mapMaker A way of creating a new map instance to store the mapped entries. * @return The target map. * @throws X If an error occurs within the mapping function. */ public static <K, U, V, M extends Map<K, V>, X extends Throwable> M mapValues(Map<K, ? extends U> source, CheckedFunction<? super U, ? extends V, ? extends X> mapper, Supplier<M> mapMaker) throws X { if (source != null) { final M mapped = mapMaker.get(); for (Entry<K, ? extends U> entry : source.entrySet()) { mapped.put(entry.getKey(), mapper.apply(entry.getValue())); } return mapped; } else { return null; } }
/** * A hybrid of {@link #ifPresent(Object, CheckedFunction)} and {@link #ifAbsent(Object, CheckedSupplier)}, * returning the application of the {@code mapperIfPresent} function to the given {@code value} if it * isn't {@code null}, or sourcing the value from the given {@code supplierIfAbsent} supplier if the * value is {@code null}. * * @param <T> Value type. * @param <U> Mapped or supplied type. * @param <X> Exception type. * @param value The value to consider. * @param mapperIfPresent The mapping function to invoke if the value is non-{@code null}. * @param supplierIfAbsent The supplier to invoke if the value is {@code null}. * @return The mapped value if the initial value isn't {@code null}, or the value produced by * the supplier otherwise. * @throws X If an error occurs inside either the mapping function or the supplier. */ public static <T, U, X extends Throwable> U ifEither(T value, CheckedFunction<? super T, ? extends U, X> mapperIfPresent, CheckedSupplier<? extends U, X> supplierIfAbsent) throws X { return value != null ? mapperIfPresent.apply(value) : supplierIfAbsent.get(); }
final List<Future<V>> submissions = new ArrayList<>(); source.forEach(item -> { submissions.add(executor.submit(() -> Exceptions.wrap(() -> mapper.apply(item), CapturedException::new))); });