/** * A function that remember/cache previous executions. * * @return A memo function. */ default Function<V, R> memoized() { if (this instanceof Memoized) { return this; } Map<Object, R> cache = new HashMap<>(); return (Function<V, R> & Memoized) value -> memo(cache, Arrays.asList(value), () -> tryApply(value)); } }
/** * * Apply this function and run the given action in case of exception. * * @param type Exception filter. * @param action Action to run when exception occurs. * @param <X> Exception type. * @return A new function. */ default <X extends Throwable> Function<V, R> onFailure(Class<X> type, java.util.function.Consumer<X> action) { return value -> fnOnFailure(() -> tryApply(value), type, action); }
/** * Apply this function or recover from a specific exception in case of exception. * * @param type Exception filter. * @param fn Exception recover. * @param <X> Exception type. * @return A new function. */ default <X extends Throwable> Function<V, R> recover(Class<? extends X> type, java.util.function.Function<X, R> fn) { return value -> fnRecover(() -> tryApply(value), type, fn); }
/** * Apply this function and unwrap any resulting exception. Useful to get clean/shorter stacktrace. * * @param type Exception to unwrap. * @param <X> Exception type. * @return A new function. */ default <X extends Throwable> Function<V, R> unwrap(Class<? extends X> type) { return value -> fnUnwrap(() -> tryApply(value), type); }
/** * Apply this function to the given argument and produces a result. * * @param v Input argument. * @return Result. */ @Override default R apply(V v) { return fn(() -> tryApply(v)); }
/** * Apply this function and returns the given default value in case of exception. * * @param defaultValue Exceptional default value. * @return A new function. */ default Function<V, R> orElse(Supplier<R> defaultValue) { return value -> fn(() -> tryApply(value), defaultValue); }
/** * Apply this function and wrap any resulting exception. * * @param wrapper Exception wrapper. * @return A new function. */ default Function<V, R> wrap(java.util.function.Function<Throwable, Exception> wrapper) { return value -> fnWrap(() -> tryApply(value), wrapper); }