/** * A function that remember/cache previous executions. * * @return A memo function. */ default Function3<V1, V2, V3, R> memoized() { if (this instanceof Memoized) { return this; } Map<Object, R> cache = new HashMap<>(); return (Function3<V1, V2, V3, R> & Memoized) (v1, v2, v3) -> memo(cache, Arrays.asList(v1, v2, v3), () -> tryApply(v1, v2, v3)); } }
/** * * 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> Function3<V1, V2, V3, R> onFailure(Class<X> type, java.util.function.Consumer<X> action) { return (v1, v2, v3) -> fnOnFailure(() -> tryApply(v1, v2, v3), type, action); }
/** * Apply this function and returns the given default value in case of exception. * * @param defaultValue Exceptional default value. * @return A new function. */ default Function3<V1, V2, V3, R> orElse(Supplier<R> defaultValue) { return (v1, v2, v3) -> fn(() -> tryApply(v1, v2, v3), defaultValue); }
/** * Apply this function to the given argument and produces a result. * * @param v1 Input argument. * @param v2 Input argument. * @param v3 Input argument. * @return Result. */ default R apply(V1 v1, V2 v2, V3 v3) { return fn(() -> tryApply(v1, v2, v3)); }
/** * Apply this function and wrap any resulting exception. * * @param wrapper Exception wrapper. * @return A new function. */ default Function3<V1, V2, V3, R> wrap( java.util.function.Function<Throwable, Exception> wrapper) { return (v1, v2, v3) -> fnWrap(() -> tryApply(v1, v2, v3), wrapper); }
/** * 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> Function3<V1, V2, V3, R> recover(Class<? extends X> type, java.util.function.Function<X, R> fn) { return (v1, v2, v3) -> fnRecover(() -> tryApply(v1, v2, v3), 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> Function3<V1, V2, V3, R> unwrap(Class<? extends X> type) { return (v1, v2, v3) -> fnUnwrap(() -> tryApply(v1, v2, v3), type); }